【问题标题】:Refinery CMS - Proper technique to link two models in an engine?Refinery CMS - 在一个引擎中链接两个模型的正确技术?
【发布时间】:2012-11-29 17:07:27
【问题描述】:

我已使用此处概述的技术 (http://www.refinerycms.com/guides/multiple-resources-in-an-extension) 将引擎添加到现有炼油厂 CMS (2.0.9) 模型中。这似乎运作良好,所有页面都存在并且可以编辑。

但是,我现在正尝试正确关联引擎中的两个 模型,以便在输入新记录期间,一个模型的外键显示为下拉“名称”而不仅仅是一个空的整数文本框。

例如,我的引擎名称是“gorts”(“地球停转之日”中的机器人)。其中两个模型是 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

所以,我想我需要修改传感器控制器 new 操作,以便它生成一个 @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

但它失败了: Refinery::Gorts::Admin::SensorsController#new 中的 NoMethodError super: Refinery::Gorts::Admin::SensorsController:0x007f86ef471d28 没有超类方法`new'

如果我注释掉“超级”行,我似乎在某处打破了链条,因为我在表单上收到了这个错误: Refinery/gorts/admin/sensors 中的 NoMethodError#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 没有影响。

在炼油厂引擎中关联两个模型以使输入表单显示相关模型的名称而不是整数键的正确方法是什么?

如果有任何 Refinery CMS 专家可以帮助我,我将不胜感激,并且我承诺会就此主题撰写一份指南,并发送给 Refinery 团队以包含在他们的指南中!

谢谢! 戴夫

【问题讨论】:

  • 我正在尝试使用装饰器来解决这个问题...
  • 只是好奇——装饰器的实验结果如何?我希望将一些引擎关联在一起并正在探索选项
  • 我从来没有让装饰师来处理这个......我所做的是@Agush概述的以下概念
  • 酷 - 谢谢。你有没有写过那个指南?如果我也能让它工作,我会帮忙的:)
  • 今天早些时候我看到你的评论时,我看到了我写指南的承诺。我明天早上第一件事就写。感谢您提供帮助!

标签: ruby-on-rails-3 crud refinerycms


【解决方案1】:

简单的方法

在: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>

而不是你之前的文本输入。

在视图上查询设备通常是不好的做法,但是这样您就不需要更改包含 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>

【讨论】:

  • 这两种方法都非常有效!我离开它“正确的方式”非常感谢!
  • 我已经编写了指南并提出了拉取请求。
  • 拉取请求已被接受并合并到 RefineryCMS!
猜你喜欢
  • 2012-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-13
  • 2017-11-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多