2010-11-08 52 views
0

我有一個簡單的模板系統,它在呈現模板時調用在模型的不同類中定義的show_me方法(有點小工具)。這些小部件最初將字符串作爲html返回。所以在我的erb中我有這樣的想法。從模型中訪問ActionView幫助程序

<% @template.widgets.each do |widget| %> 
    <%= widget.show_me %>  
<% end %> 

由於部件的看法變得更加複雜,我開始用諧音來呈現他們,稱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時丟失了一些東西。

任何想法如何解決這個問題?也歡迎任何關於整體設計的建議:)

回答

-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 %> 

顯然可能不成爲確切的解決方案你的情況,但只是一個指導,告訴你可以做些什麼來保持你的代碼清潔。 :)

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 

這樣,你可以使用面嚮對象的技術共享部件之間的演示文稿的邏輯,你可以通過從公司演示隔離您的信息保持Rails的快樂(和未來的開發者)。