2009-06-22 52 views
2

我是一个Ruby on Rails的新手,在关联对象的情况下,有一个关于观点的逻辑问题:显示关联对象

我的模型类似于

class Post < ActiveRecord::Base 
    has_many :comments 
end 

class Comment < ActiveRecord::Base 
    belongs_to :post 
end 

而我想显示为类似于所有帖子的列表以及每个帖子的前三个评论。

所以,我不停的后位指示索引操作简单

class PostController < ApplicationController 
    #.. 
    def index 
    @posts = Post.find(:all) 
    end 
    #.. 
end 

现在在views/posts/index.html.erb我可以做这样的事情@posts.comments 我可以循环的前三项。但是,如何访问模型(在这种情况下是相关模型)中正常完成的功能,如视图(或控制器)中的排序,范围等?

回答

1

您应该避免在视图中编写复杂的业务登录。在这种情况下,您的执行非常简单,您可以在视图中编写所有代码。它应该看起来像这样

<% @posts.each do |post| %> 
    <% @post.comments.all(:limit => 3, :order => "created_at DESC").each do |comment| %> 
     do something 
    <% end %> 
<% end %> 

有一些可能的改进。首先,使用named_scope。

class Post < ActiveRecord::Base 
    has_many :comments 
end 

class Comment < ActiveRecord::Base 
    belongs_to :post 
    named_scope :recent, proc { |limit| :limit => limit || 3, :order => "created_at DESC") } 
    # you can also hard-code the limit value (ScottD) 
    named_scope :recent, :limit => 3, :order => "created_at DESC" 
end 


<% @posts.each do |post| %> 
    <% @post.comments.recent.each do |comment| %> 
     do something 
    <% end %> 
<% end %> 

如果我是对的,.each可以被删除。

<% @posts.each do |post| %> 
    <% @post.comments.recent do |comment| %> 
     do something 
    <% end %> 
<% end %> 

如果您愿意,也可以定义一个自定义关系(这对于非常复杂的关系)。

+1

我会对你的例子做一些小的修改: 1)你不需要指定范围的proc。只是做named_scope:最近:限制=> 3,:订单... 2)在视图中,我会使用部分: <%= render:partial“comment”,:collection => @ post.comments.recent% > Rails将发送由named_scope返回的数组,并为您呈现局部循环。 – scottd 2009-06-22 19:18:27

+0

谢谢ScottD!我更新了这个例子。 – 2009-06-22 19:36:13

1

你可以使用在其指定的类似限制的关联一个find方法:在你看来

@post.comments.find(:all, :limit => 3) 

,或者您可以在Post模型像创建另一个协会:

has_many :first_three_comments, :limit => 3, :class_name => "Comment" 

然后你可以参考像

@ post.first_three_comments.each do | comment | ...

希望有所帮助。