0

@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>做成一个链接,指向存档视图?

注意:在我的应用程序中,毫秒将被替换为月份,就像在存档视图中一样。

4

2 回答 2

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
于 2013-08-25T10:25:39.640 回答
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
于 2013-08-25T10:25:36.510 回答