1

I have a join table called ProductFeatures which joins Product and Feature instances via has_many: ..., through: product_features, and has an additional column called rating.

I want to add .rating method on Feature which will return a rating float based on specific product instance that is calling it. Something like:

Product.find(...).features.first.rating #=> should specific product_feature rating

I've tried:

  • passing caller_id as an argument to .rating. This works, but makes me use product.id each time I want to get a specific product rating feature.
  • Obtaining a caller instance id from inside the method using .caller (with binding_of_caller, or vanilla Ruby), but .caller does not seem to let me get a calling instance id, and would also fail in tests as the caller would be the spec's ExampleGroup
Community
  • 1
  • 1
dimitry_n
  • 2,939
  • 1
  • 30
  • 53
  • Do you use `has_and_belongs_to_many` or `has_many :through`? – Michał Młoźniak Aug 21 '16 at 20:04
  • @MichałMłoźniak `has_many :through` – dimitry_n Aug 21 '16 at 20:05
  • So why not just use `product_features` association for this: `p = Product.find(...); p.product_features.first.rating`? – Michał Młoźniak Aug 21 '16 at 20:09
  • @MichałMłoźniak that's the goal. but how do I get the product instance id inside Feature's `rating` method? Say my query is something like `product.features.first.rating`. Then inside the Rating class, I'd have something like `def rating; ProductFeature.find_by(feature_id: feature.id, product_id ???).rating`, right? – dimitry_n Aug 21 '16 at 20:12
  • What I am suggesting is not to add `rating` method to `Feature` class, but just use `product_features` association. Perhaps you can somehow implement this, but it will make your code harder to understand. – Michał Młoźniak Aug 21 '16 at 20:14

1 Answers1

0

You can get these data with other way.

  • I want to add #rating method on Feature which will return a rating float based on specific product instance that is calling it. Something like:
## Controller add this code snipped
   get_feature = Product.find(...).features
   rating(get_feature)

   protected

   def rating(get_all_feature)
     all_rating = []
     get_all_feature.each do |feature|
       all_rating <<  feature.product_features.each { |u| u.rating }
     end
     all_rating
   end

Hope this help you!

Gupta
  • 8,882
  • 4
  • 49
  • 59
  • thanks! thing is, I want to pull a specific rating. The above will return a collection of `ProductFeature` instances where the feature_id matches self.id. – dimitry_n Aug 21 '16 at 19:58
  • Same problem. This returns a collection, while a feature.rating should be pulled from ProductFeatures.rating. That's why `.rating` is added to the join table so that its unique per `product.feature` – dimitry_n Aug 21 '16 at 20:15