渲染部分时自动调用控制器方法

时间:2013-06-17 16:21:55

标签: ruby-on-rails ruby-on-rails-3.2

我有一部分需要在运行之前运行一些控制器逻辑而没有问题。有没有办法将部分与某些控制器逻辑相关联,无论何时渲染它都会运行?

例如,这是我当前的代码:

MyDataController:

class MyDataController < ApplicationController
  def view
    @obj = MyData.find(params[:id])
    run_logic_for_partial
  end

  def some_method_i_dont_know_about
    @obj = MyData.find(params[:id])
    # Doesn't call run_logic_for_partial
  end

  def run_logic_for_partial
    @important_hash = {}
    for item in @obj.internal_array
      @important_hash[item] = "Important value"
    end
  end
end

view.html.erb:

Name: <%= @obj.name %>
Date: <%= @obj.date %>
<%= render :partial => "my_partial" %>

some_method_i_dont_know_about.html.erb:

Name: <%= @obj.name %>
User: <%= @obj.user %>

<%# This will fail because @important_hash isn't initialized %>
<%= render :partial => "my_partial" %>

_my_partial.html.erb:

<% for item in @obj.internal_array %>
  <%= item.to_s %>: <%= @important_hash[item] %>
<% end %>

即使未从控制器显式调用该方法,如何在呈现run_logic_for_partial时确保调用_my_partial.html.erb?如果我不能,Rails中是否有任何常用模式来处理这些情况?

2 个答案:

答案 0 :(得分:3)

您尝试做的事情与Rails控制器/视图的设计使用方式有关。以不同的方式构建事物会更好。为什么不把run_logic_for_partial放到帮助器中,让它接受一个参数(而不是隐含地处理@obj)?

要查看“助手”视图的示例,请查看此处:http://guides.rubyonrails.org/getting_started.html#view-helpers

答案 1 :(得分:3)

您应该为这种逻辑使用视图助手。如果使用rails generate生成资源,则资源的帮助文件应该已存在于app/helpers目录中。否则,您可以自己创建:

# app/helpers/my_data.rb
module MyDataHelper
    def run_logic_for_partial(obj)
        important_hash = {}
        for item in obj.internal_array
            important_hash[item] = "Important value" // you'll need to modify this keying to suit your purposes
        end
        important_hash
    end
end

然后,在您的部分中,将您想要操作的对象传递给您的帮助者:

# _my_partial.html.erb
<% important_hash = run_logic_for_partial(@obj) %>
<% for item in important_hash %>
    <%= item.to_s %>: <%= important_hash[item] %>
<% end %>

或者:

# app/helpers/my_data.rb
module MyDataHelper
    def run_logic_for_partial(item)
        # Do your logic
        "Important value"
    end
end

# _my_partial.html.erb
<% for item in @obj.internal_array %>
    <%= item.to_s %>: <%= run_logic_for_partial(item) %>
<% end %>

编辑:

正如Ian Kennedy所指出的那样,这个逻辑也可以合理地抽象为模型中的便捷方法:

# app/models/obj.rb
def important_hash
    hash = {}
    for item in internal_array
        important_hash[item] = "Important value"
    end
    hash
end

然后,您将在以下部分中以下列方式访问important_hash属性:

# _my_partial.html.erb
<% for item in @obj.important_hash %>
    <%= item.to_s %>: <%= item %>
<% end %>