我有一个简单的模板系统,在渲染模板时调用在我的模型的不同类(有点小部件)中定义的show_me
方法。这些小部件最初将html作为字符串返回。所以在我的问题中我有这样的想法。
<% @template.widgets.each do |widget| %>
<%= widget.show_me %>
<% end %>
随着小部件的视图变得越来越复杂,我开始使用partials来渲染它们,从我的小部件中调用ActionView::Base
渲染方法(请不要呕吐):
def show_me
# ... specific calculations and other magic.
ActionView::Base.new(MyApp::Application.config.view_path).render(:partial => "widgets/weather_widget", :locals => {:data => data, :settings => settings})
end
所以,这就像一个魅力(真的......)但是当我想在小部件特定部分内部使用帮助器(例如。widgets/_weater_widget.html.erb
)时,它们不起作用。例如。 javascript_tag
提出
can't convert nil into String
actionpack (3.0.0) lib/action_view/helpers/asset_tag_helper.rb:790:in `join'
actionpack (3.0.0) lib/action_view/helpers/asset_tag_helper.rb:790:in `rails_asset_id'
actionpack (3.0.0) lib/action_view/helpers/asset_tag_helper.rb:813:in `rewrite_asset_path'
actionpack (3.0.0) lib/action_view/helpers/asset_tag_helper.rb:742:in `compute_public_path'
actionpack (3.0.0) lib/action_view/helpers/asset_tag_helper.rb:256:in `javascript_path'
actionpack (3.0.0) lib/action_view/helpers/asset_tag_helper.rb:822:in `javascript_src_tag'
actionpack (3.0.0) lib/action_view/helpers/asset_tag_helper.rb:362:in `block in javascript_include_tag'
actionpack (3.0.0) lib/action_view/helpers/asset_tag_helper.rb:362:in `collect'
actionpack (3.0.0) lib/action_view/helpers/asset_tag_helper.rb:362:in `javascript_include_tag'
我认为在创建ActionView :: Base时我遗失了一些东西。
有任何想法如何解决这个问题?此外,欢迎任何有关整体设计的建议:)
答案 0 :(得分:3)
您可以通过模型调用视图帮助程序,但Rails会在每一步都为您提供帮助。 Rails不希望你做这样的事情。
考虑引入小部件演示者类。它可以像app/helpers,
一样生活在
module WidgetHelper
class WidgetPresenter < Struct.new(:widget)
def show_me
render(:partial => "widgets/#{widget.class}/show", :locals => {:widget => widget })
end
end
def show_widgets(template)
@template.widgets.map do |widget|
WidgetPresenter.new(widget).show_me
end.join
end
end
通过这种方式,您可以使用OO技术在窗口小部件演示者之间共享表示逻辑,并且可以通过将信息与其演示文稿隔离来保持Rails的快乐(以及未来的开发人员)。
答案 1 :(得分:-1)
请关注所有事情,MVC不会从模型中呈现视图代码。 :(总有一种更好的方法可以做到。
示例:
class Widget < ActiveRecord::Base
def name
"weather_widget"
end
def settings
## something here
end
def data
## calculations here
end
end
module WidgetHelper
def render_widget(widget)
render(:partial => "widgets/_#{widget.name}", :locals => {:data => widget.data, :settings => widget.settings})
end
end
<% @template.widgets.each do |widget| %>
<%= render_widget(widget) %>
<% end %>
显然,这可能不是您情况的确切解决方案,但只是向您展示可以保持代码清洁的一些指南。 :)