Как обновить дополнительные атрибуты в модели соединения? - PullRequest
0 голосов
/ 29 марта 2020

У меня есть три модели, связанные с использованием ассоциации has_many through. Я решил использовать эту модель после прочтения некоторой документации, которая гласила: «Вы должны использовать has_many: through, если вам нужны проверки, обратные вызовы или дополнительные атрибуты в модели соединения».

Документы

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 для dispatched в моей первой попытке и во вторую секунду я получаю undefined_method за order_dispatched!.

Я думаю, может быть, я не до конца понимаю, что передавалось в документах. Или, может быть, это не идеальный способ справиться с этим типом отношений. Я также проверил ответы, но есть несколько старых вопросов, на которые нет ответа.

1 Ответ

0 голосов
/ 29 марта 2020

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 вместо where. find_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)
...