我正在尝试将对象融合为单个流。
我创建了一个名为Newsfeed的新模型和控制器。我有它所以新闻源has_many:消息和has_many:图像和图像和消息belongs_to:newsfeed。我现在正在设置控制器,我有:
def index
@messages = Messages.all
@images = Images.all
@feed = ?
end
如何将它们融合在一起,以便它们可以从两者中拉出来并按时间顺序排列,每个都需要单独制作?
非常感谢任何帮助,谢谢。
答案 0 :(得分:18)
你可以做一些事情:
控制器:
def index
messages = Messages.all
images = Images.all
@feed = (messages + images).order_by(&:created_at)
end
查看index.html.erb:
<%= render @feed %>
查看_feed.html.erb:
<% if feed.is_a? Message %>
<%= render "message", :locals => {:message => feed}%>
<% else %>
<%= render "image", :locals => {:image => feed}%>
<% end %>
并添加2个部分_message.html.erb和_image.html.erb
答案 1 :(得分:7)
我确信这可以从它的贫民窟多态性中得到简化,但它对我有用,而且我与“我如何结合所有这些模型结果?”进行了相同的斗争?!
我使用像你一样的单独模型和观察者:
class NewsfeedObserver < ActiveRecord::Observer
observe Message, Image
def after_save(object)
@item = Newsfeed.create(
:item_id => object.id,
:item_type => object.class.to_s
)
end
end
然后在Newsfeed模型中,您可以随意拉动和整理:
def self.get_items
item_list = []
items = find(:all, :order => "created_at DESC", :limit => 30)
items.collect{ |i| i.item_type.constantize.find(i.item_id) }
end
然后只需拉动它们,然后在您的视图中显示。
#Controller
def index
@feed = Newsfeed.get_items
end
继续前进我可能会开始将更多内容打包到流跟踪模型中,以便在其他表上保存点击量,但希望你明白这一点。
答案 2 :(得分:1)
这感觉有点像一个问题,虽然我没有时间深入挖掘它,但这里有一些初步的想法:
您可以将要显示的两种类型的项目组合到一个数组中,然后根据两者之间应该是常见的字段对这个数组进行排序(想到created_at)以使它们按时间顺序排列顺序。
在视图中,您可以使用此单个集合进行迭代,然后使用帮助程序和唯一的部分来以正确的格式呈现项目。这可以通过在尝试在视图中显示对象类型时检查对象类型来完成。
有些事情:
if item.is_a? Message
render :partial => 'message', :locals => {:message => item }
elsif item.is_a? Image
render :partial => 'image', :locals => {:image => item }
end
希望这会有所帮助!
编辑:要组合数组,您只需使用'+'运算符将它们附加在一起,因为Ruby中的数组不需要包含单个对象类型。您的Messages.all和Images.all调用会为您提供对象数组,因此请尝试
@messages + @images
你应该有你的组合数组。
编辑#2:如果我自己写这篇文章,我可能会像这样处理这些观点:在顶层,只需将您的Feed集合传递给部分,该部分用于呈现单个项目:
render :partial => "item", :collection => @feed
这将为@feed中的每个项目呈现'_item.html.erb'部分。此外,它每次都会给部分一个名为'item'的局部变量,这是该特定迭代的@feed中的项。
现在,我可能会将'_item'部分变得非常简单,就像这样:
<%= display_item(item) %>
其中display_item是视图外的辅助方法,用“is_a?”实现从上面输入逻辑,为项目选择正确的显示格式。
我之所以将其分解,是因为它利用了一些漂亮的rails功能(将集合传递给部分而不是自己循环遍历集合)然后将逻辑拉出到帮助器中(甚至是模型,如果这是有道理的)因为它简化了你的观点是有用的。尽可能将逻辑排除在视图之外通常是一种很好的做法,因为这样的逻辑很难测试,你的观点将变得非常难以阅读。