【问题标题】:How to update extra attributes on a join model?如何更新连接模型上的额外属性?
【发布时间】:2020-03-29 10:24:31
【问题描述】:

我有三个使用has_many through 关联的模型。在阅读了一些文档后,我决定使用此模型:“如果您需要验证、回调或连接模型上的额外属性,您应该使用 has_many :through。”

Docs

用户.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!

我想我可能不完全理解文档中传递的内容。或者,这不是处理这种关系的理想方式。我也查了答案,但有几个老问题没有答案。

【问题讨论】:

    标签: ruby-on-rails rails-activerecord


    【解决方案1】:

    Order.where(id: params[:order_id], vendor_id: v.id) 返回 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) 只返回一个实例,则应使用find_by 而不是wherefind_by 只返回一条符合给定条件的记录。

    # 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)
    

    【讨论】:

    • 非常感谢...因为where,我试图只返回给定条件的一条记录。
    猜你喜欢
    • 2017-04-21
    • 2017-04-18
    • 2010-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-17
    相关资源
    最近更新 更多