2

ここ ( http://www.refinerycms.com/guides/multiple-resources-in-an-extension ) で説明されている手法を使用して、エンジンを既存の製油所 CMS (2.0.9) モデルに追加しました。これはうまく機能しているようで、すべてのページが存在し、編集可能です。

ただし、新しいレコードの入力中に、1 つのモデルの外部キーが単なる空の整数テキスト ボックスではなく、ドロップダウンの「名前」として表示されるように、エンジン内の2 つのモデルを適切に関連付けようとしています。

たとえば、私のエンジン名は「gorts」(「地球が静止する日」のロボット)です。モデルのうちの 2 つはdevicesensorであり、次のように適切に関連付けられています: \extension\gorts\models\refinery\gorts\device.rb

module Refinery
  module Gorts
    class Device < Refinery::Core::BaseModel
      attr_accessible :name, :gort_id, :picture_id, :position
      acts_as_indexed :fields => [:name]
      validates :name, :presence => true, :uniqueness => true
      belongs_to :picture, :class_name => '::Refinery::Image'
      belongs_to :gort
      has_many :sensor
    end
  end
end

およびsensor.rb:

module Refinery
  module Gorts
    class Sensor < Refinery::Core::BaseModel
      attr_accessible :device_id, :name, :sublocation, :sensortype, :uidval, :position
      acts_as_indexed :fields => [:name, :sublocation, :sensortype, :uidval]
      validates :name, :presence => true, :uniqueness => true
      belongs_to :device
      has_many :reading

    end
  end
end

そこで、 @devices変数を生成するようにセンサー コントローラーの新しいアクションを変更する必要があると考えました。フォームを変更してそれをドロップダウンに変えるのは簡単です。ただし、私が試みたすべてが失敗するか、@devices の設定に失敗します。ここに私が試したいくつかのことがあります:

まず、これをgorts/admin/sensors_controller.rbに追加してみました:

 def new
        # DC Attempting to get @devices defined so we can use for a drop-down
        logger.info("Seeding all devices from admin/sensors_controller new")
        @devices = Device.find(:all)
        super
    end

しかし、次のエラーで失敗します: NoMethodError in Refinery::Gorts::Admin::SensorsController#new super: no superclass method `new' for Refinery::Gorts::Admin::SensorsController:0x007f86ef471d28

「スーパー」行をコメントアウトすると、フォームで次のエラーが発生するため、チェーンをどこかで切断しているように見えます: NoMethodError in Refinery/gorts/admin/sensors#new

Showing /Users/cclogicimac/rails_projects/cclogic_app/vendor/extensions/gorts/app/views/refinery/gorts/admin/sensors/_form.html.erb where line #1 raised:

undefined method `model_name' for NilClass:Class
Extracted source (around line #1):

1: <%= form_for [refinery, :gorts_admin, @sensor] do |f| -%>
2:   <%= render '/refinery/admin/error_messages',
3:               :object => @sensor,
4:               :include_object_name => true %>
Trace of template inclusion: vendor/extensions/gorts/app/views/refinery/gorts/admin/sensors/new.html.erb

そこで、別のアプローチを試みました: /gorts/sensors_controller.rb を変更します (gorts/admin の代わりに...)。

したがって、このコードを/gorts/admin/sensors_controller.rbに配置すると、

def new
    # DC Attempting to get @devices defined so we can use for a drop-down
    logger.info("Seeding all devices from sensors_controller new")
    @devices = Device.find(:all)
    super
end

エラーは発生しませんが、/views/refinery/gorts/admin/sensors/_form.html.erb にアクセスすると、@devices はnilです。また、ログ ステートメントが表示されず、super にコメントしても影響がないため、このコードがヒットすることはないと思います。

入力フォームに整数キーではなく関連モデルの名前が表示されるように、製油所エンジンで 2 つのモデルを関連付ける適切な方法は何ですか?

Refinery CMS の専門家が私を助けてくれるなら、私はそれを感謝し、このトピックに関するガイドを作成し、ガイドに含めるために Refinery チームに送信することを約束します!

ありがとう!デイブ

4

1 に答える 1

3

シンプルな方法

中: extensions/gorts/app/views/refinery/gorts/admin/sensors/_form.html.erb

追加するだけです:

<div class="field">
  <%= f.label :device -%>
  <%= f.select(:device_id, Refinery::Gorts::Device.all.collect {|d| [d.name, d.id] })%>
</div>

以前のテキスト入力の代わりに。

通常、ビューでデバイスの do を照会するのは悪い習慣ですが、この方法では、crudify とブラック マジックを含むデフォルトのリファイナリー管理コントローラーを変更する必要はありません。

正しい方法

中: vendor/extensions/gorts/app/controllers/refinery/gorts/admin/sensors_controller.rb

module Refinery
  module Gorts
    module Admin
      class SensorsController < ::Refinery::AdminController
        before_filter :find_all_devices

        crudify :'refinery/gorts/sensors',
                :title_attribute => 'name', :xhr_paging => true

        protected

        def find_all_devices
          @devices = Refinery::Gorts::Device.all
        end

      end
    end
  end
end

中: extensions/gorts/app/views/refinery/gorts/admin/sensors/_form.html.erb

<div class="field">
  <%= f.label :device -%>
  <%= f.select(:device_id, @devices.collect {|d| [d.name, d.id] })%>
</div>
于 2012-12-20T10:32:48.830 に答える