0

show_meテンプレートをレンダリングするときに、モデルのさまざまなクラス(ちょっとウィジェット)内で定義されたメソッドを呼び出す単純なテンプレートシステムがあります。これらのウィジェットは元々、htmlを文字列として返しました。だから私のエルブでは、私はこのようなことを考えています。

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

ウィジェットのビューがより複雑になるにつれて、ActionView::Baseウィジェット内からrenderメソッドを呼び出して、パーシャルを使用してウィジェットをレンダリングし始めます(まだスローしないでください:)

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を作成するときに、何かが足りないと思います。

これを解決する方法について何か考えはありますか?また、全体的なデザインに関する提案も歓迎します:)

4

2 に答える 2

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 (および将来の開発者) を満足させることができます。

于 2010-11-08T21:47:31.830 に答える
-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 %>

明らかに、それはあなたの状況の正確な解決策ではないかもしれませんが、コードをきれいに保つためにできることを示すためのガイドにすぎません. :)

于 2010-11-08T21:38:11.960 に答える