6

好吧..我是Rails的新手,我知道這已經被問過,但我仍然對如何解決以下常見問題感到困惑。我可以讓協會工作,但神奇地工作,並開始有壞習慣的軌道是不是我想做的事情。爲has_many和belongs_to創建Rails模型關聯

假設我正在構建博客。我有兩個資源:文章和用戶。每個用戶都有很多文章和每篇文章屬於一個用戶:

rails g scaffold User name:string email:string 
rails g scaffold Article user_id:integer title:string content:string 

用戶模型:

class User < ActiveRecord::Base 
    has_many :articles 
end 

文章型號:現在

class Article < ActiveRecord::Base 
    belongs_to :user 
end 

,對我的文章的索引,我可以這樣做:

…table headers... 
<% @articles.each do |article| %> 
    <tr> 
    <td><%= article.user.name %></td> 
    <td><%= article.title %></td> 
    <td><%= article.desc %></td> 
    <td><%= article.content %></td> 
    <td><%= link_to 'Show', article %></td> 
    <td><%= link_to 'Edit', edit_article_path(article) %></td> 
    <td><%= link_to 'Destroy', article, confirm: 'Are you sure?', method: :delete %></td> 
    </tr> 
<% end %> 
</table> 

我所需要的用於用戶名的模型關聯將在respond_to之前的索引操作上放置「@articles = Article.all」。很酷!

如果我想在我的主頁上使用我的Home控制器上的索引操作列出所有這些文章(我正在跳過分頁,爲簡單起見),該怎麼辦?

我知道我可以做這樣的事情在家庭控制器:

class HomeController < ApplicationController 
    def index 
    @articles = Article.joins(:user) 
    end 
end 

...然後我可以在我的首頁 - >索引視圖訪問這些數據:

<div class="row"> 
    <% @articles.each do |article| %> 
    <div> 
     <h3><%= link_to article.title, 
     :controller => "articles", :action => "show", :id => article.id %></h3> 
     <small>Posted on <%= article.created_at %> by 
     <a href="#"><%= article.user.name %></a></small> 
    </div> 
    <% end %> 
</div> 

首先問:訪問所有文章的用戶數據時,我應該使用a:joins還是:includes?看起來他們都工作,但我想知道在這種情況下哪一個是正確的,哪一個通常表現得更快。

@articles = Article.joins(:user) 

航班嗎

@articles = Article.includes(:user) 

第二個問題:在我的腳手架條(建設遷移),我應該用USER_ID:整數或用戶:引用。他們做同樣的事情,還是比其他人更喜歡?如果我使用:integer作爲字段類型,建議我還爲它添加一個索引(add_index:articles,:user_id)?我發現了一個很好的RailsCast,它的解釋很棒,但我想知道其他人是否有其他意見。

如果有幫助,我在Rails 3.2.2上。

謝謝!

回答

3

第一個問題:

要檢索所有與他們的用戶數據的條款以高效的方式,則必須使用

@articles = Article.includes(:user) 

您將在每篇文章中獲得數據庫中所有文章的列表其用戶已經獲取。

With @articles = Article.joins(:user)您將只獲得包含用戶的文章,並且當您對這些文章中的任何文章執行article.user時,它會生成一個新的SQL請求。

欲瞭解更多信息:http://guides.rubyonrails.org/active_record_querying.html(如果你還沒有閱讀這套指南,我強烈建議你現在就做)。

第二個問題:

我用的是user_id:integer形式。我不確定user:references可以在rails g scaffold命令行中使用。 「articles.user_id」列上的索引將提高查找特定用戶的文章時的檢索速度。僅當您的應用程序執行此類搜索時才添加此索引。

+0

感謝您的澄清。從日誌中,我可以看到傳遞給我的數據庫的查詢,但我不確定Rails如何將「包含」與「連接」對待。 '索引'的答案也非常有幫助! – JohnnyCoder 2012-01-27 19:46:21

5
  1. 您應該使用@articles = Article.all :include => :user來檢索您的記錄。有關更多信息,請參閱Rails :include vs. :joins以瞭解爲什麼這通常比:joins更快。 (基本上,它給你沒有重複的相同信息。)

  2. 當涉及到遷移時,Rails具有belongs_to關聯的快捷方式。使用belongs_to :user,Rails將自動包含user_id列(類型爲integer)。

例子:

class CreateArticle < ActiveRecord::Migration 
    def self.up 
    create_table :articles do |t| 
     t.belongs_to :user # Creates 'user_id' column 
     t.timestamps 
    end 
    end 
end 
+0

謝謝!我不知道這個'屬於'遷徙的速記,我一定會把它添加到我的兵工廠。 – JohnnyCoder 2012-01-27 20:39:16