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