Lovish Choudhary
Lovish Choudhary

Reputation: 167

Active record query for a query in rails

I am working on a rails app which has three models 'request', 'service' and 'price'. Request and services have a has_many_through relationship, and service and price have a has_one-belongs-to relationship i.e a service has one price and price belongs to service.

The model with relationship

 class Request < ActiveRecord::Base
    has_many :request_services
    has_many :services, through: :request_services
 end

 class RequestService < ActiveRecord::Base
   belongs_to :service
   belongs_to :request
 end

 class Service < ActiveRecord::Base
    has_many :request_services
    has_many :requests, through: :request_services
    has_one :price
 end

 class Price < ActiveRecord::Base
    belongs_to :service
 end

Now a user will create a new request which can have many services. So, I want to write a query to select the prices of the services that a user has selected in his request.

So far I have written this query,

1) To find the services in the request

 Request.find(1).services

2) After this I want to get the prices of selected services, so I am writing

 Request.find(1).services.prices

But this query is throwing error.

The error i am getting when running this query in rails console

Can anybody please help me in writing the query to fetch the prices of all the selected services

  Request Load (0.2ms)  SELECT  "requests".* FROM "requests" WHERE "requests"."id" = ? LIMIT 1  [["id", 1]]
  NoMethodError:   Service Load (0.3ms)  SELECT "services".* FROM "services" INNER JOIN "request_services" ON "services"."id" = "request_services"."service_id" WHERE "request_services"."request_id" = ?  [["request_id", 1]]
 undefined method `prices' for #<Service::ActiveRecord_Associations_CollectionProxy:0x007f4ec4c41bb0>

Upvotes: 0

Views: 57

Answers (3)

trh
trh

Reputation: 7339

Essentially your query states: "For this request (1) give me the Price of each related Service"

But chaining doesn't work that way. I'm unsure why you're using has_many-through called RequestService, but regardless, you have several options to get the price data for a request, a join, iterate-and-add-to-array, or the most simplistic add has-many-through on prices.

e.g.

Iterate & Add to Array

prices = []
Request.find(1).services.each { |s| prices << s.price }

Has Many Through

class Request < ActiveRecord::Base
  has_many :request_services
  has_many :services, through: :request_services
  has_many :prices, through: :services
 end

Which would let you do:

Request.find(1).prices

Upvotes: 0

Axel Tetzlaff
Axel Tetzlaff

Reputation: 1364

Maybe you can tackle it the other way around:

Price.joins(service: { request_services: :request}).where('requests.id = ?', request_id)

This gets all prices related to the request with the given id

Upvotes: 2

joost
joost

Reputation: 173

You need to call Request.find(1).services.price (price is singular) since each service has only one price

Upvotes: 0

Related Questions