如何更新连接模型的额外属性?
How to update extra attributes on a join model?
我有三个使用 has_many through
关联关联的模型。在阅读了一些文档后,我决定使用这个模型:"You should use has_many :through if you need validations, callbacks, or extra attributes on the join model."
user.rb
has_many :orders
has_many :vendors, through: :orders
order.rb
belongs_to :user
belongs_to :vendor
vendor.rb
has_many :orders
has_many :users, through: :orders
模式看起来像这样
create_table "orders", force: :cascade do |t|
t.integer "vendor_id"
t.integer "user_id"
t.integer "servings", default: 1, null: false
t.string "location"
t.string "payment_method"
t.boolean "paid", default: false, null: false
t.boolean "dispatched", default: false, null: false
t.boolean "delivered", default: false, null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.integer "meal_id"
t.index ["user_id"], name: "index_orders_on_user_id"
t.index ["vendor_id"], name: "index_orders_on_vendor_id"
end
所以现在,我正在寻找如何更新订单模型中的属性,特别是布尔值。
我尝试过的:
def dispatched
v = Vendor.find_by(vendorname: params[:_vendorname])
order= Order.where(id: params[:order_id], vendor_id: v.id)
order.dispatched = !order.dispatched
json: order, status: :ok
end
当这不起作用时,我想如果我从模型本身调用一个函数,我就可以更新它。
#order_controller.rb
def dispatched
v = Vendor.find_by(vendorname: params[:_vendorname])
order= Order.where(id: params[:order_id], vendor_id: v.id)
order.order_dispatched!
json: order, status: :ok
end
#order.rb
def order_dispatched!
self.dispatched = !self.dispatched
save!
end
第一次尝试时,我得到的错误是 undefined_method
for dispatched
,在第二次尝试中,我得到的错误是 undefined_method
for order_dispatched!
。
我想我可能没有完全理解文档中传递的内容。或者,这可能不是处理此类关系的理想方式。我也查过答案,但是有几个老问题没有答案
Order.where(id: params[:order_id], vendor_id: v.id)
returns ActiveRecord::Relation
,不是 Order
实例。
如果你不关心性能,你可以使用each
迭代关系。
# Before
order.order_dispatched!
#After
order.each {|o| o.order_dispatched!}
如果您打算 Order.where(id: params[:order_id], vendor_id: v.id)
到 return 只有一个实例,您应该使用 find_by
而不是 where
。 find_by
return只有一条记录符合给定的条件。
# Before
order= Order.where(id: params[:order_id], vendor_id: v.id)
#After
order= Order.find_by(id: params[:order_id], vendor_id: v.id)
我有三个使用 has_many through
关联关联的模型。在阅读了一些文档后,我决定使用这个模型:"You should use has_many :through if you need validations, callbacks, or extra attributes on the join model."
user.rb
has_many :orders
has_many :vendors, through: :orders
order.rb
belongs_to :user
belongs_to :vendor
vendor.rb
has_many :orders
has_many :users, through: :orders
模式看起来像这样
create_table "orders", force: :cascade do |t|
t.integer "vendor_id"
t.integer "user_id"
t.integer "servings", default: 1, null: false
t.string "location"
t.string "payment_method"
t.boolean "paid", default: false, null: false
t.boolean "dispatched", default: false, null: false
t.boolean "delivered", default: false, null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.integer "meal_id"
t.index ["user_id"], name: "index_orders_on_user_id"
t.index ["vendor_id"], name: "index_orders_on_vendor_id"
end
所以现在,我正在寻找如何更新订单模型中的属性,特别是布尔值。
我尝试过的:
def dispatched
v = Vendor.find_by(vendorname: params[:_vendorname])
order= Order.where(id: params[:order_id], vendor_id: v.id)
order.dispatched = !order.dispatched
json: order, status: :ok
end
当这不起作用时,我想如果我从模型本身调用一个函数,我就可以更新它。
#order_controller.rb
def dispatched
v = Vendor.find_by(vendorname: params[:_vendorname])
order= Order.where(id: params[:order_id], vendor_id: v.id)
order.order_dispatched!
json: order, status: :ok
end
#order.rb
def order_dispatched!
self.dispatched = !self.dispatched
save!
end
第一次尝试时,我得到的错误是 undefined_method
for dispatched
,在第二次尝试中,我得到的错误是 undefined_method
for order_dispatched!
。
我想我可能没有完全理解文档中传递的内容。或者,这可能不是处理此类关系的理想方式。我也查过答案,但是有几个老问题没有答案
Order.where(id: params[:order_id], vendor_id: v.id)
returns ActiveRecord::Relation
,不是 Order
实例。
如果你不关心性能,你可以使用each
迭代关系。
# Before
order.order_dispatched!
#After
order.each {|o| o.order_dispatched!}
如果您打算 Order.where(id: params[:order_id], vendor_id: v.id)
到 return 只有一个实例,您应该使用 find_by
而不是 where
。 find_by
return只有一条记录符合给定的条件。
# Before
order= Order.where(id: params[:order_id], vendor_id: v.id)
#After
order= Order.find_by(id: params[:order_id], vendor_id: v.id)