在Rails中渲染多态对象

时间:2011-08-29 14:00:32

标签: ruby-on-rails ruby-on-rails-3

对于只想要问题的人,这里是:

当您在对象上调用render时,有没有办法指定要查看的文件夹?我不想指定视图,只想指定要查看的文件夹。

对于想要上下文的人:

我正在开发一个活动流系统(看起来像google + / facebook)。

我有“活动”,就像google + feeds(或facebook,或其他什么!)。所以,我有一个简单的循环显示每个活动,它们绑定到以下对象之一(多态):User,Group,Comment,Note。

在我看来,渲染一个活动(views/activities/_activity.html.erb),我有

<%= render activity.object %>

其中activity.object是对绑定对象的引用(User,Group,Note,Comment)。如果是用户,则转到views/users/_user.html.erb并呈现它。对于某个群组,views/groups/_group.html.erb

这很好用。但是,我发现我的活动中的组渲染不应该与组列表页面中的渲染相同。有没有办法在对象上调用render时指定要查看的文件夹?所以我的:

<%= render activity.object %>

会变成:

<%= render activity.object, :folder => 'views/activities/' %>

请注意,我不想直接指定哪个视图,因为我不想为活动中的每个可能类型的对象(用户,组,注释,注释)执行操作。我希望现在具有相同的行为,这意味着如果它找到views/activities/_user.html.erb,它将使用该视图加载活动中的任何用户而不是views/users/_user.html.erb中的用户。

由于

3 个答案:

答案 0 :(得分:3)

我不知道任何文件夹类型选项,但是当我这样做时,我通常会这样做:

<%= render "activities/#{activity.object.class.name.underscore}" %>

这会给你类似的行为。

编辑 Dominic下面的一个要点,如果您的类嵌套在命名空间中,则必须包含适当的结构。

 module Foo
   class Bar < ActiveRecord::Base
   end
 end

 # class.name is Foo::Bar, underscored is 'foo/bar'

 <%= render "activities/#{activity.object_type.underscore}" %>
 # will be in
 activities/foo/_bar.html

答案 1 :(得分:2)

在当前的Rails(3.2.9)中,您可以在模型上定义to_partial_path方法,告诉它在哪里查看。

例如,你可以这样做:

class User
  def to_partial_path; "user"; end
end
然后,

Rails会查找相对于您正在调用渲染的视图的_user.html.erb。

答案 2 :(得分:0)

我自己的方法,我在polymorphic_render gem中提取 - 为特殊部分添加后缀,但将该部分存储在资源文件夹中。

在您的情况下,views/users/_user.html.erb将具有非常常见的用户表示(可能在用户列表呈现中使用),但views/users/_user_activity.html.erb将为用户活动呈现特殊部分。

插入部分内容非常简单,只需<%= polymorphic_render activity.object, :activity %>