【问题标题】:Accessing properties with has_many :though使用 has_many 访问属性:虽然
【发布时间】:2013-04-09 01:47:53
【问题描述】:

在下面的代码中,我有两个通过has_many :through 关联的模型。 Component 模型也是 belongs_to Category 模型。我正在尝试从Collection 访问Category.title 属性,尽管Component 类似于:@collection.components[:id].category.title

在下面的代码“:components”中放入:

[#<Component id: 23, name: "l-shaped-desks", title: "L-Shaped Desks", category_id: 10, created_at: "2013-04-07 00:18:07", updated_at: "2013-04-07 00:18:07">, #<Component id: 25, name: "writing-tables", title: "Writing Tables", category_id: 10, created_at: "2013-04-07 00:18:29", updated_at: "2013-04-07 00:18:29">]

每个"#&lt;Component&gt;" 都是从生成的复选框中选中的。

问题是我不知道如何访问这些信息。我试过:components[0].category.title 但得到错误:

undefined method `category' for :components:Symbol

_form.html.haml

= form_for @collection do |f|
  - if @collection.errors.any?
    #error_explanation
      %h1= "#{pluralize(@collection.errors.count, "error")} prohibited this collection from being saved:"
      %ul
        - @collection.errors.full_messages.each do |msg|
          %li= msg

  - Category.products.each_slice(2) do |column|
    .column
      - column.each do |category|
        .column-group
          %h1 
            = category.title
          - category.components.each do |component|
            .checkbox
              = check_box_tag "component#{component.id}", component.id, @collection.components.include?(component), :name => 'collection[component_ids][]'
              = label_tag "component#{component.id}", component.title

  .field
    = f.label :title
    = f.text_field :title
  .field
    = f.label :components
    = f.text_field :components //This will fill a text_input with [#<Component...
    / = f.text_field :components[0].category.title //This does not work
  .actions
    = f.submit 'Save'

category.rb

class Category < ActiveRecord::Base
  default_scope order('id ASC')

  CATEGORY_KINDS = [["Product", 0],["Page", 1]]

  scope :products, where(:kind => 0)
  scope :pages, where(:kind => 1)

  attr_accessible   :name, 
                    :title, 
                    :kind,
                    :section, 
                    :component

  has_many          :sections
  has_many          :components

  before_save       :create_name

  private

  def create_name
    self.name = title.parameterize
  end
end

component.rb

class Component < ActiveRecord::Base
  default_scope order('components.id ASC')

  attr_accessible         :category_id, 
                          :name, 
                          :title,
                          :collection_ids,
                          :style_ids

  has_many                :collection_components, :dependent => :destroy
  has_many                :collections,   :through => :collection_components

  has_many                :component_styles
  has_many                :styles,        :through => :component_styles

  belongs_to              :category

  validates_presence_of   :category
  validates_presence_of   :title

  before_save             :create_name

  private

  def create_name
    self.name = title.parameterize
  end
end

collection.rb

class Collection < ActiveRecord::Base
  default_scope order('collections.id ASC')

  attr_accessible               :style_id, 
                                :name, 
                                :title,
                                :component_ids


  has_many                      :collection_components, :include => :component
  has_many                      :components,            :through => :collection_components
  accepts_nested_attributes_for :collection_components, :allow_destroy => true

  belongs_to                    :style

  validates_presence_of         :style
  validates_presence_of         :title
  validates_presence_of         :component_ids

  before_save                   :create_name

  private

  def create_name
    self.name = title.parameterize
  end
end

collection_component.rb

class CollectionComponent < ActiveRecord::Base
  attr_accessible :collection_id, 
                  :component_id

  belongs_to      :collection
  belongs_to      :component
end

【问题讨论】:

  • 你想在哪里引用title?在您显示的表单视图中?
  • 很抱歉。我在底部附近的 _form 中添加了一些 cmets。如果需要进一步澄清,请告诉我。

标签: ruby-on-rails associations has-many-through


【解决方案1】:

如果您尝试编辑相关模型的属性,通常可以为相关模型使用嵌套的fields_for。有关详细信息,请参阅 Rails Form Helpers guide 中的 fields_for 文档。

但是,如果您主要只是对引用关联 Category 实例的 title 属性的正确方法感兴趣,这应该可以工作(用于访问 first 组件的 Category):

@collection.components.first.category.title

(请注意,我已将 [0] 替换为 first,但它们实际上是相同的。)

【讨论】:

  • 我会试试的,谢谢。但是,我还想在应用程序的其他区域通过ComponentCollection 访问Category.title。例如,在Collections 的index.html.haml 中,我希望能够显示CategoriesCollection 相对于它的Components 属于哪个。我想更大的问题是,访问#&lt;component&gt; 元素中的信息的正确语法是什么。
  • 那么对于后续的Components,它是“第二”、“第三”、...“第二十五”、...“一千三百”吗?
  • 不,如果您硬编码始终使用第一个元素,则仅使用该样式。如果您需要获取索引偏移量,请继续使用[0][1] 等。
  • 显然,或者使用变量循环。例如,@collection.components.each { |component| component.category.title # do something with that value }
  • 是的,它现在似乎可以使用普通的数组表示法了。我不知道为什么我以前有这么多问题。感谢您的关注!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-09
  • 1970-01-01
  • 2013-09-18
  • 1970-01-01
相关资源
最近更新 更多