hansottowirtz
hansottowirtz

Reputation: 692

Ruby on Rails: ActiveRecord::StatementInvalid can't cast ActiveRecord::StatementInvalid

I have this Rails code:

def newfood
  memberproduct = MemberProduct.new
  memberproduct.product_id = Product.where(:barcode_number => params[:barcode_number]).id
  memberproduct.expiration_date = params[:expiration_date]
  memberproduct.member_id = current_member.id
  memberproduct.save
end

I need the id of the product. The 3rd line is wrong.

I have a MemberProduct table with a product_id field, an expiration_date field and a member_id field (current_member comes from devise) I have a Product table with a barcode_number field and a name field.

I get this error:

ActiveRecord::StatementInvalid in FoodController#newfood TypeError: can't cast ActiveRecord::Relation::ActiveRecord_Relation_Product to string: INSERT INTO "member_products" ("created_at", "expiration_date", "member_id", "product_id", "updated_at") VALUES (?, ?, ?, ?, ?)

What am I doing wrong?

Upvotes: 0

Views: 2170

Answers (2)

user419017
user419017

Reputation:

Depending on version of Rails, you should be able to:

Rails 3: Product.find_by_barcode_number(params[:barcode_number])

Rails 4: Product.find_by(barcode_number: params[:barcode_number])

You can simplify your action as so:

mprod = current_member.build_member_product(expiration_date: params[:expiration_date])
mprod.product = Product.find_by(barcode_number: params[:barcode_number])
mprod.save

Though you probably want to deal with validations and such (if mprod.save .. else)

Upvotes: 1

janfoeh
janfoeh

Reputation: 10328

Try

memberproduct.product = Product.where(:barcode_number => params[:barcode_number]).first

memberproduct.product_id is the database column where Rails stores the ID of the product associated to your memberproduct. Usually, these are not used directly; instead, the association name is.

So both of these work:

def newfood
  memberproduct                 = MemberProduct.new
  product                       = Product.where(:barcode_number => params[:barcode_number]).first
  memberproduct.product         = product
  memberproduct.expiration_date = params[:expiration_date]
  memberproduct.member          = current_member

  memberproduct.save
end

and

def newfood
  memberproduct                 = MemberProduct.new
  product                       = Product.where(:barcode_number => params[:barcode_number]).first
  memberproduct.product_id      = product.id
  memberproduct.expiration_date = params[:expiration_date]
  memberproduct.member_id       = current_member.id

  memberproduct.save
end

but the first form is more common. If you assign an object like product or member to the association, Rails is smart enough to ask the object for its ID and use it automatically.

Also, Product.where potentially returns multiple results. Since you only expect one, add .first to return only the first match.

Upvotes: 1

Related Questions