Ruby on Rails:ActiveRecord :: StatementInvalid无法转换ActiveRecord :: StatementInvalid

时间:2013-12-14 19:27:11

标签: ruby-on-rails ruby class

我有这个Rails代码:

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

我需要产品的ID。 第3行错了。

我有一个MemberProduct表,其中包含product_id字段,expiration_date字段和member_id字段(current_member来自devise) 我有一个Product表,其中包含barcode_number字段和name字段。

我收到此错误:

  

FoodController中的ActiveRecord :: StatementInvalid #newfood TypeError:   无法将ActiveRecord :: Relation :: ActiveRecord_Relation_Product转换为   string:INSERT INTO“member_products”(“created_at”,   “expiration_date”,“member_id”,“product_id”,“updated_at”)VALUES(?,   ?,?,?,?)

我做错了什么?

2 个答案:

答案 0 :(得分:1)

尝试

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

memberproduct.product_id是数据库列,其中Rails存储与您的memberproduct关联的产品的ID。通常,这些不是直接使用的;相反,关联名称是。

所以这两个都有效:

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

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

但第一种形式更常见。如果您为关联指定了productmember这样的对象,Rails就足够聪明地向对象询问其ID并自动使用它。

此外,Product.where可能会返回多个结果。由于您只需要一个,因此请添加.first以仅返回第一个匹配项。

答案 1 :(得分:1)

根据Rails的版本,您应该能够:

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

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

您可以简化操作:

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

虽然你可能想要处理验证等(if mprod.save .. else