1

カスタム RedCloth タグからビュー ヘルパーを呼び出そうとしていますが、まったく運がありません。私が見つけることができるすべての例では、カスタム タグ メソッドを作成し、他のメソッドをまったく呼び出さずにリテラル文字列を返します。

毎週のスケジュールを出力するカスタム RedCloth タグを作成しようとしています。このコードは、アプリケーションの他の領域でも使用されるため、既にヘルパーに記述されています。

だから、私の問題が要約される(大幅に削減された)コードは次のとおりです。

アプリ/ビュー/ページ/show.html.erb:

<%= raw redcloth @page.content %

アプリ/ヘルパー/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

そしてレールは言う:

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'

それで、私は何をすべきですか?私は完全に明らかな何かを見逃しており、恥をかいて頭を埋める必要がありますか、それとも、好きな場所からヘルパーを呼び出すことは単に不可能ですか? 自分の ScheduleHelper モジュールのすべてのコードを複製するカスタム タグを取得する必要がありますか?

どんな助けでも大歓迎です。

4

1 に答える 1

3

さて、私は自分で許容できる解決策にたどり着きました。だから私はいい子になって分かち合います。

ヘルパーの代わりに、パーシャルをレンダリングするクラスを使用するので、質問は実際には「カスタム RedCloth タグからパーシャルを呼び出す」になるはずです。

(私はコードにコメントしていません。それはかなり自己文書化されているはずです)

app/helpers/schedule_tag.rb:

module ScheduleTag
  def schedule(options)
    Schedule.new.render Date.today.monday
  end
end

app/helpers/schedule.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

アプリ/ビュー/スケジュール/_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>

余談ですが、これを試してみると、RedCloth がオプション文字列をエスケープするという問題に遭遇する可能性があります。==オプションを文字どおりに渡すには、オプションを 'sで囲みます。例えばschedule. =={"weeks":["this","next"]}==。これはちょっと危険な面もあるかもしれないので、意地悪なところはしっかりチェックしておきましょう。

于 2011-12-09T07:46:02.303 に答える