カスタムレッドクロスタグからヘルパー(またはパルティアルをレンダリング)を使用する
-
29-10-2019 - |
質問
私はカスタムレッドクロスタグからビューヘルパーを呼び出そうとしていますが、まったく運がありません。他のメソッドを呼び出すことなく、カスタムタグメソッドを作成してリテラル文字列を作成して返すことができるすべての例が見つかります。
毎週のスケジュールを出力するために、カスタムレッドクロスタグを作成しようとしています。アプリケーションの他の領域でも使用されているため、ヘルパーですでに書かれているコード。
だから、ここに私の問題が要約する(大幅に削減された)コードは次のとおりです。
app/views/page/show.html.erb:
<%= raw redcloth @page.content %
app/helpers/pages_helper.rb:
module PagesHelper
def redcloth(content)
r = RedCloth.new content
r.extend ScheduleTag
r.to_html
end
end
app/helpers/schedule_tag.rb:
module ScheduleTag
include ScheduleHelper
def schedule(options)
build_schedule
end
end
app/helpers/schedule_helper.rb:
module ScheduleHelper
def build_schedule
content_tag :div do
content_tag :span,
"Why won't my helper just work by magic like the rest of " \
"rails seems to?"
end
end
end
実行された場合、Railsは次のものを主張します。
TypeError in Pages#show
Showing /blah/blah/blah/app/views/pages/show.html.erb where line #1 raised:
can't convert Symbol into Integer
Extracted source (around line #1):
1: <%= raw redcloth @page.content %>
Rails.root: /blah/blah/blah
Application Trace | Framework Trace | Full Trace
app/helpers/schedule_helper.rb:3:in `build_schedule'
app/helpers/schedule_tag.rb:42:in `schedule'
app/helpers/pages_helper.rb:22:in `redcloth'
app/views/pages/show.html.erb:1:in _app_views_pages_show_html_erb___756530284_81829440__535015588'
app/controllers/pages_controller.rb:23:in `show'
ヘルパーをクラスに使用することを変更することで少し進歩を遂げることができますが、そのクラスはまだ標準的なヘルパーを使用して問題を抱えています。
/app/helpers/schedule_builder.rb:
class ScheduleBuilder
extend ActionView::Helpers::TagHelper
def self.build_schedule
content_tag :div do
content_tag :span,
"Why won't my helper just work by magic like the rest of " \
"rails seems to?"
end
end
end
そして、Railsは言う:
NoMethodError in Pages#show
Showing /blah/blah/blah/app/views/pages/show.html.erb where line #1 raised:
undefined method `output_buffer=' for ScheduleBuilder:Class
Extracted source (around line #1):
1: <%= raw redcloth @page.content %>
Rails.root: /blah/blah/blah
Application Trace | Framework Trace | Full Trace
app/helpers/schedule_builder.rb:5:in `build_schedule'
app/helpers/schedule_tag.rb:42:in `schedule'
app/helpers/pages_helper.rb:22:in `redcloth'
app/views/pages/show.html.erb:1:in `_app_views_pages_show_html_erb___756530284_81708830__535015588'
app/controllers/pages_controller.rb:23:in `show'
それで、私は何をすべきですか?私は完全に明白な何かを逃していて、恥ずかしくて頭を埋めるべきですか、それともどこからでも1つの空想からヘルパーに電話することはできませんか? ScheduleHelperモジュールのすべてのコードを複製するために、カスタムタグを取得するだけで、カスタムタグを取得する必要がありますか?
どんな助けも大歓迎です。
解決
さて、私は自分で受け入れられる解決策に来ました。だから私は良い小さな男の子になり、共有します。
ヘルパーの代わりに、部分的にレンダリングするクラスを使用するので、質問は本当に「カスタムレッドクロスタグから部分的なものを呼び出す」になるはずです。
(私はコードにコメントしていません、それはかなり自己文書化する必要があります)
app/helpers/schedule_tag.rb:
module ScheduleTag
def schedule(options)
Schedule.new.render Date.today.monday
end
end
アプリ/ヘルパー/スケジュール.RB:
class Schedule < ActionView::Base
include ActionView::Helpers::TagHelper
include Rails.application.routes.url_helpers
def render week
self.view_paths = "app/views"
super :partial => "schedule/schedule",
:locals => { :week => week,
:schedule => ScheduledClass.get_schedule(week) }
end
end
app/view/schedule/_schedule.html.erb:
<table id="schedule">
<tbody>
<tr>
<td>Hoop-dee-doo, it works!</td>
<%= content_tag :td do %>
<%= link_to "so do tag & route helpers", happy_monkey_path(:happy => "very") %>
<% end %>
</tr>
</tbody>
</table>
少しさておき、これを試してみると、レッドクロスがオプションの弦を逃れる問題につまずくかもしれません。内部のオプションを囲むだけです ==
文字通りオプションを渡すようにすること。例えば schedule. =={"weeks":["this","next"]}==
. 。これは危険な面で少しあるかもしれないので、必ず厄介さを確認してください。