Liz
Liz

Reputation: 1437

Rails Undefined Method for Has_Many/Belongs_To Relationship

I have an app where an admin has to create a custom price per user before they buy a product. A pricing belongs_to a user and a product, a user has_many pricings, and a product has_many pricings. The routes are like this:

  devise_for :users, :controllers => { registrations: 'registrations' }
  resources :users, only: [:show]
  resources :products do
    resources :pricings
  end

On the users#show page, I am trying to get a list of the pricings for that user. I have the following in my users_controller:

def show
    @user = User.find(params[:id])
    @products_with_pricing = Product.joins(:pricings).group("products.id").having("count(products.id) > ?",0)
end

And this on my users#show view:

<% @products_with_pricing.each do |product| %>
    <% if product.pricing.user == current_user %>
        <%= product.name %>
    <% end %>
<% end %>

This shows all the product names for all the pricings if I omit the if ....== current_user statement, but with that statement I am getting a NoMethod error on the if statement line that says:

undefined method 'pricing' for # Did you mean? pricings`

Can anyone set me straight as to the best way to accomplish this goal?

Upvotes: 1

Views: 81

Answers (1)

PhilVarg
PhilVarg

Reputation: 4811

product has_many pricings

That means that to get a product's pricings, you need to call product.pricings, which will return a collection of pricings. The error youre seeing is correct, product does not have a pricing method that returns one pricing object, it has a pricings method that returns many pricings.

If your goal is to only fetch products whose pricings also belong to the user, i'd recommend adjusting your SQL query to accomplish this

Product.joins(pricings: :users)
.where(pricings: { user: { id: current_user.id } })
.group("products.id")
.having("count(products.id) > ?",0)

note: you may need to mess with the plurality of pricings and users in the where and joins

This query is introducing a new joins and a where clause that will filter products whose pricings have a user with an id of the current user, so you wont need to have the if statement at all

Upvotes: 2

Related Questions