【问题标题】:Has many through: How to Add record and fill fields in join table有很多通过:如何在连接表中添加记录和填写字段
【发布时间】:2016-04-12 20:32:20
【问题描述】:

我有这些模型:

class Item < ActiveRecord::Base
  has_many :users, through: :user_items
  has_many :user_items
end

class User < ActiveRecord::Base
  has_many :items, through: :user_items
  has_many :user_items
end

class UserItem < ActiveRecord::Base
  belongs_to :user
  belongs_to :item
end

create_table "user_items", force: :cascade do |t|
  t.integer  "user_id",
  t.integer  "item_id",
  t.integer  "amount"
end

我想知道向用户添加项目并在连接表中设置数量的最佳方法。

我正在做这样的事情:

user = User.first
item = Item.first
UserItems.create(user: user, item: item, amount: 5)

但我不太喜欢它,有时它不能正常工作,因为如果我运行

user.items   #=> []

我得到一个空数组,它似乎没有在 DB 中得到新的变化。

那么,有没有简单的方法可以做到这一点?像这样直观的东西会很完美:

user.user_items << item, amount: 4

好的,所以我这样做了,它奏效了:

user.user_items.create!(item: item, amount: 5) 

但是这样就没有了:

user.user_items << item, amount: 4 

现在它更优雅了。但我仍然有关于缓存请求的问题。如果我运行 user.items。它仍然是空的。任何想法?我试过用 inverse_of 什么都没有。我想避免重新加载或类似的方法。如果可能的话,我想以透明的方式进行

【问题讨论】:

  • user.items.reload?我的意思是,一切都完美存储,user.items 因为缓存返回一个空数组。
  • 我个人会选择这个 SO 答案 (stackoverflow.com/questions/31982343/…),它将为您提供所需的一切(包括设置金额值)。否则,您仍然可以分两行完成。
  • @mudasobwa,是的,没错,一切都完美存储。但是我认为如果我必须写reload 这不是一个好习惯,你不觉得吗?这就是为什么我正在寻找一种干净的方式来做到这一点。谢谢!
  • 如果你想要一个明确的说法“用户有 5 个项目”,你可以使用User.first.user_items &lt;&lt; [item] * 5,但你仍然需要调用 save 来使更改持久化。
  • 这就是鸡蛋鸡的问题。要么你想要缓存,要么你不想要。您可以覆盖def items; super.reload; end 以禁用此特定元素的缓存,但通常模型无法知道不同表的数据库内容已更改。

标签: ruby-on-rails ruby has-many-through


【解决方案1】:

你可以这样做:

user = User.first
item = Item.first
user.user_items.create!(item_id: item.id, amount: 5)

或:

user.items.push(items)

【讨论】:

  • 我认为第一个可以工作,但你如何设置第二个中的金额值?谢谢!
  • @quin 是的,第二个只会为没有金额的用户添加项目。如果您还想添加金额user.user_items.push(item_id: item.id, amount: 5)
【解决方案2】:

试试这个

user.user_items.push(item: item, amount: 5)

或者如果你想在不推送新值的情况下反映项目,试试这个

UserItem.create(user: user, item: item, amount: 5)
user.reload
user.items # this will reflect newly loaded values now

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-02
    • 2011-02-18
    • 2016-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多