GoYoshi
GoYoshi

Reputation: 373

undefined method 'id_tag' for ActiveRecord_Associations_CollectionProxy

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

Answers (3)

JK Gunnink
JK Gunnink

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

Sravan
Sravan

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

potashin
potashin

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

Related Questions