Reputation: 373
In my CrawlProduct class I want to get the id_tag from the table ProductInfo:
class CrawlProduct < ActiveRecord::Base
belongs_to :crawl_link
css_id = self.crawl_link.domain.product_infos.id_tag
end
The table CrawlProducts
has a foreign key crawl_link
and the table CrawlLinks
has a foreign key domain
which comes from the table Domain
of course. And ProductInfo belongs to domain.
class CrawlProduct < ActiveRecord::Base
belongs_to :crawl_link
end
class CrawlLink < ActiveRecord::Base
belongs_to :domain
has_one :crawl_product
end
class Domain < ActiveRecord::Base
has_many :crawl_links
has_many :product_infos
end
class ProductInfo < ActiveRecord::Base
belongs_to :domain
end
But at the end, I always receive the following error:
undefined method `id_tag' for #<ProductInfo::ActiveRecord_Associations_CollectionProxy:0x0055d72e423640>
How can I access the id_tag
? There is no column missing as far as I know.
Edit: after the answers I get a different error.
NameError: undefined local variable or method `id_tag' for #<CrawlProduct:0x0055d72fcd9fe0>
I don't know why I'm getting this problem. Here is how I create the id_tag:
class Domain < ActiveRecord::Base
domain = Domain.create(domain: 'https://www.example.com')
product_info = ProductInfo.create(domain: domain, id_tag: 'some content')
end
Upvotes: 0
Views: 577
Reputation: 153
I think you're accessing product_infos
incorrectly. You need to specify which one you want, and then access the id_tag from it.
Rails is correctly telling you that
undefined method `id_tag' for #<ProductInfo::ActiveRecord_Associations_CollectionProxy:0x0055d72e423640>
because the relationship is has_many.
If you wanted to just access the first one the database pulls out (in no specific order, unless you specify), you could just do
css_id = self.crawl_link.domain.product_infos.first.id_tag
Upvotes: 1
Reputation: 18647
self.crawl_link.domain.product_infos will return a group of objects so, you cannot retrieve id_tag(a field) from a collection.
Instead you can use,.
class CrawlProduct < ActiveRecord::Base
belongs_to :crawl_link
def some_action
css_ids = self.crawl_link.domain.product_infos.pluck(:id_tag)
(or)
css_ids = self.crawl_link.domain.product_infos.map(&:id_tag)
end
end
Upvotes: 1
Reputation: 44581
self.crawl_link.domain.product_infos
is a collection of instances, so you can't call instance methods on it, to call it on each item you should either iterate collection with each
or collect ids with map
. To collect just ids without creating instances you can use pluck
:
self.crawl_link.domain.product_infos.pluck(:id_tag)
Upvotes: 1