has_many :through association, "No Method Error" in rails console in shell, NoMethodError: undefined method for #<ActiveRecord::Relation:>
has_many :through association, "No Method Error" in rails console in shell, NoMethodError: undefined method for #<ActiveRecord::Relation:>
我正在开发 rails 3 应用程序中的一项功能。我有一个新模型,叫做 Box,它有很多 "Product"(s)。 has_and_belongs_to_many 给我带来了麻烦。所以我制作了一个名为 BoxProduct 的新模型。它看起来像这样:
class Box < ActiveRecord::Base
attr_accessible :name, :product_ids
has_many :box_products, :class_name => 'BoxProduct'
has_many :products, through: :box_products
accepts_nested_attributes_for :box_products
end
class BoxProduct < ActiveRecord::Base
attr_accessible :box, :product
belongs_to :box
belongs_to :product
end
class Product < ActiveRecord::Base
include Concerns::Notifiable
include ThinkingSphinx::Scopes
attr_accessible :box_ids
has_many :box_products
has_many :boxes, through: :box_products
end
-我 运行 进入的第一个问题是:当我在 rails 控制台中访问一个 Box 时:
[1] pry(main)> b = Box.first
Box Load (2.0ms) SELECT "boxes".* FROM "boxes" LIMIT 1
=> #<Box id: 1, name: "Test", image: nil, ....
[2] pry(main)> b.products
Product Load (1.6ms) SELECT "products".* FROM "products" INNER JOIN
"box_products" ON "products"."id" = "box_products"."product_id"
WHERE "box_products"."box_id" = 1
=> []
[3] pry(main)> b = Box.where("id" => 2)
Box Load (0.8ms) SELECT "boxes".* FROM "boxes" WHERE
"boxes"."id" = 2
=> [#<Box id: 2, name: "Yoo", image: "image.jpeg" ....
[4] pry(main)> b.products
NoMethodError: undefined method `products' for #
<ActiveRecord::Relation:0x007f3b68c30208>
from /home/vagrant/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/activerecord-3.2.13/lib/active_record/relation/delegation.rb:45:in `method_missing'
但是,在 CMS 中,在框视图页面中,@box.products returns table 中每个框的产品作为工具,对于我拥有的所有框条目到目前为止创建。
您的第一个问题很容易解决:请注意 where
不会 return 数据库中的单个对象,即使只找到一个条目。 where
return 是一个 ActiveRecord::Relation,在您的问题上下文中充当列表。
Box.where("id" => 2)
#=> [#<Box id: 2, ... # Note the `[` at the beginning of the line
而且你不能在这个 Relation
上调用 products
,因为 products
是在 Box
上定义的,而不是在 Relation
.[=22= 上定义的]
您可以根据需要以不同的方式解决此问题。
您可以遍历该列表并在每个条目上调用 products
:
Box.where(id: 2).map(&:products)
Box.where(id: 2).includes(:products)
或者您可以使用仅 return 单个元素的方法:
Box.find(2).products
Box.find_by(id: 2).products
Box.where(id: 2).take.products
Box.where(id: 2).first.products
我正在开发 rails 3 应用程序中的一项功能。我有一个新模型,叫做 Box,它有很多 "Product"(s)。 has_and_belongs_to_many 给我带来了麻烦。所以我制作了一个名为 BoxProduct 的新模型。它看起来像这样:
class Box < ActiveRecord::Base
attr_accessible :name, :product_ids
has_many :box_products, :class_name => 'BoxProduct'
has_many :products, through: :box_products
accepts_nested_attributes_for :box_products
end
class BoxProduct < ActiveRecord::Base
attr_accessible :box, :product
belongs_to :box
belongs_to :product
end
class Product < ActiveRecord::Base
include Concerns::Notifiable
include ThinkingSphinx::Scopes
attr_accessible :box_ids
has_many :box_products
has_many :boxes, through: :box_products
end
-我 运行 进入的第一个问题是:当我在 rails 控制台中访问一个 Box 时:
[1] pry(main)> b = Box.first
Box Load (2.0ms) SELECT "boxes".* FROM "boxes" LIMIT 1
=> #<Box id: 1, name: "Test", image: nil, ....
[2] pry(main)> b.products
Product Load (1.6ms) SELECT "products".* FROM "products" INNER JOIN
"box_products" ON "products"."id" = "box_products"."product_id"
WHERE "box_products"."box_id" = 1
=> []
[3] pry(main)> b = Box.where("id" => 2)
Box Load (0.8ms) SELECT "boxes".* FROM "boxes" WHERE
"boxes"."id" = 2
=> [#<Box id: 2, name: "Yoo", image: "image.jpeg" ....
[4] pry(main)> b.products
NoMethodError: undefined method `products' for #
<ActiveRecord::Relation:0x007f3b68c30208>
from /home/vagrant/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/activerecord-3.2.13/lib/active_record/relation/delegation.rb:45:in `method_missing'
但是,在 CMS 中,在框视图页面中,@box.products returns table 中每个框的产品作为工具,对于我拥有的所有框条目到目前为止创建。
您的第一个问题很容易解决:请注意 where
不会 return 数据库中的单个对象,即使只找到一个条目。 where
return 是一个 ActiveRecord::Relation,在您的问题上下文中充当列表。
Box.where("id" => 2)
#=> [#<Box id: 2, ... # Note the `[` at the beginning of the line
而且你不能在这个 Relation
上调用 products
,因为 products
是在 Box
上定义的,而不是在 Relation
.[=22= 上定义的]
您可以根据需要以不同的方式解决此问题。
您可以遍历该列表并在每个条目上调用 products
:
Box.where(id: 2).map(&:products)
Box.where(id: 2).includes(:products)
或者您可以使用仅 return 单个元素的方法:
Box.find(2).products
Box.find_by(id: 2).products
Box.where(id: 2).take.products
Box.where(id: 2).first.products