1

I'm playing with data in my rails console testing some relationships and it seems to be only outputting the first record of an array.

I have an variable called c which is an instance of the Comparison class in my project.

I have a relationship set up so I can call c.products and it will return me an array of all the products in that comparison which in this case is 2.

The problem is when I call:

c.products it returns only the first product out of the 2.

c.products[1] returns nil.

y c.products a more detailed version of the same data shows both products.

c.products.count returns 2.

Here is what it looks like in rails c:

c.products
=> [#<Product id: 1, category_id: 3, name: "Camera", description: "erererer", brand: "Canon", quantity: 3, star_rating: 4, price: 299.0, created_at: "2014-06-18 20:26:34", updated_at: "2014-06-19 06:40:34">]

c.products.count
   (0.5ms)  SELECT COUNT(*) FROM "products" INNER JOIN "compared_products" ON "products"."id" = "compared_products"."product_id" WHERE "compared_products"."comparison_id" = $1  [["comparison_id", 2]]
=> 2

and y c.products condensed it to show only up to the last product as returns a lot of data.

y c.products
--- &10 !ruby/object:ActiveRecord::Associations::CollectionProxy
association: !ruby/object:ActiveRecord::Associations::HasManyThroughAssociation
  reflection: &1 !ruby/object:ActiveRecord::Reflection::ThroughReflection
    macro: :has_many
    name: :products
    scope: 
    options:
      :through: :compared_products
    active_record: &2 !ruby/class 'Comparison'
    klass: &3 !ruby/class 'Product'
    plural_name: products
    collection: true
    automatic_inverse_of: false
    type: 
    foreign_type: products_type
    constructable: true
    source_reflection_name: :product
    class_name: Product
    chain:
    - *1
    - !ruby/object:ActiveRecord::Reflection::AssociationReflection
      macro: :has_many
      name: :compared_products
      scope: 
      options: {}
      active_record: *2
      klass: !ruby/class 'ComparedProduct'
      plural_name: compared_products
      collection: true
      automatic_inverse_of: 
      type: 
      foreign_type: compared_products_type
      constructable: true
      class_name: ComparedProduct
      foreign_key: comparison_id
      active_record_primary_key: id
    scope_chain:
    - []
    - []
  owner: !ruby/object:Comparison
    attributes:
      id: 2
      user_id: 1
      name: Jacks Electronics Comparison
      created_at: 2014-06-20 16:12:36.828154000 Z
      updated_at: 2014-06-20 16:12:36.828154000 Z
  loaded: true
  target:
  - !ruby/object:Product
    attributes:
      id: 1
      category_id: 3
      name: Camera
      description: erererer
      brand: Canon
      quantity: 3
      star_rating: 4
      price: 299.0
      created_at: 2014-06-18 20:26:34.276570000 Z
      updated_at: 2014-06-19 06:40:34.776216000 Z
jckly
  • 831
  • 1
  • 11
  • 22

1 Answers1

2

As you can see c.products didn’t trigger sql query, that means it is cached. c.products.count on the other hand triggers a query and tell you actual information from database. So your c.products possibly changed through other association or by hand directly in database. To receive actual products do c.products.reload, to count cached products(without sql triggering) do c.products.size

See detailed explanation here https://stackoverflow.com/a/18997294

Community
  • 1
  • 1
Rustam Gasanov
  • 15,290
  • 8
  • 59
  • 72