我在两个控制器中定义了一个实例变量@posts_by_month
,用于两个视图:
帖子控制器:
class PostsController < ApplicationController
def index
@posts = Post.all
@posts_by_month = Post.all.group_by { |post| post.created_at.strftime("%L") }
respond_to do |format|
format.html # index.html.erb
format.json { render json: @posts }
end
end
.
.
end
档案管理员:
class ArchivesController < ApplicationController
def index
@posts_by_month = Post.all.group_by { |post| post.created_at.strftime("%B") }
end
end
发布索引视图:
<h1>Listing posts</h1>
.
.
.
<div>
<% @posts_by_month.each do |millisecond, posts| %>
<p><%= millisecond %>milliseconds <%= posts.count %></p>
<% end %>
</div>
档案索引视图:
<% @posts_by_month.each do |monthname, posts| %>
<%= monthname %>
<ul>
<% posts.each do |post| %>
<h3><%= post.title %></h3>
<p><%= post.body %></p>
<% end %>
</ul>
<% end %>
我有两个问题。有没有什么方法可以定义@posts_by_month
实例变量,这样我就可以让两个视图都可以使用它而不必在每个控制器中重复它?
其次,有没有办法可以将<p><%= millisecond %>milliseconds <%= posts.count %></p>
的毫秒部分变成一个导致存档视图的链接?
注意:在我的应用程序中,毫秒将替换为存档视图中的月份。
答案 0 :(得分:2)
当执行一个动作(又称渲染)时,实例结束了。没有更多的实例变量。
View中的实例变量不是真实的实例变量。 View和Controller属于不同的类,它们如何共享实例?实际情况是,Rails所做的是将这些实例变量从Controller实例复制到View实例。
所以你问题的答案是:不。
但你仍然可以通过应用程序控制器中的私有方法来干燥代码,与PostsController和ArchiveController共享。
class ApplicationController
private
def posts_by_time(arg)
Post.all.group_by { |post| post.created_at.strftime(arg) }
end
end
class PostsController < ApplicationController
def index
@posts = posts_by_time "%L"
# ...
end
end
class ArchievesController < ApplicationController
def index
@posts = posts_by_time "%B"
# ...
end
end
答案 1 :(得分:1)
是的,您可以减少相同变量的重复。一种方法是使用过滤器:
在应用程序控制器中定义一个方法:
class ApplicationController < ActionController::Base
private
def find_post_by_month
@posts_by_month = Post.all.group_by { |post| post.created_at.strftime("%L") }
end
end
然后在存档和发布控制器内:
class ArchivesController < ApplicationController
before_filter :find_post_by_month, :only => :index
...
end
class PostsController < ApplicationController
before_filter :find_post_by_month, :only => :index
...
end
这将为您提供@posts_by_month变量的值。
并且,为了建立所提及文本的链接,您应该使用以下代码:
<p><%= link_to "#{millisecond} milliseconds", path %></p> # Replace path with your url