【问题标题】:Rails - first_or_create adding duplicate records?Rails - first_or_create 添加重复记录?
【发布时间】:2012-08-01 04:37:43
【问题描述】:

我的 Rails 应用程序中有一些种子,我正试图掌握这些种子。我将从有问题的代码开始:


make = Make.where(value: 'Alfa Romeo').first_or_create
model = make.models.where(value: '147').first_or_create
trim = model.trims.where(value: '1.6 TS 3d (2001 - 2005)').first_or_create
values = [
 {value: '2001 (X)'},
 {value: '2001 (Y)'},
 {value: '2001 (51)'},
 {value: '2002 (51)'},
 {value: '2002 (02)'},
 {value: '2002 (52)'},
 {value: '2003 (52)'},
 {value: '2003 (03)'},
 {value: '2003 (53)'},
 {value: '2004 (53)'},
 {value: '2004 (04)'},
 {value: '2004 (54)'},
 {value: '2005 (54)'},
 {value: '2005 (05)'}
]
values.each do |item|
  trim.model_years.where(item).first_or_create
end

我对这段代码的期望是它可以创建或定位品牌、型号和装饰,然后将适当的车型年份与装饰相关联。

然而,正在发生的情况是创建了重复的模型年份 - 例如,它没有将装饰与“2001 (X)”相关联,而是创建了一个值为“2001 (X)”的新记录 -需要明确的是,它的行为就像我使用的是 create,而不是 first_or_create。

任何人都可以提出为什么会发生这种情况并帮助我纠正它吗?

编辑:为避免混淆,我调整了上面的代码以反映我当前的代码,没有第一个答案中引用的 find_or_create_by 问题。上面的代码仍在创建重复项。

编辑 2:我突然想到我的代码可能从根本上出错了 - 我正在尝试做的是在 trim 和 model_year 之间创建关联(设置为多对 -许多关系)。因此,也许我出错的地方是我正在创建记录,而实际上我只想找到现有记录并添加关联。

因此,我应该使用声明关联而不创建新对象的语句,而不是 first_or_create。

因此,我已将我的声明修改为以下内容,这是有效的:

trim.model_years << ModelYear.where(item).first_or_create

感谢大家的帮助!

【问题讨论】:

  • 请注意,我在 Make、Model 或 Trim 上没有得到任何重复项,这可能会很有用;唯一的重复是 Model_years。

标签: ruby-on-rails ruby-on-rails-3 activerecord


【解决方案1】:

这里有一些更正:

make = Make.find_or_create_by_value('Alfa Romeo')
model = make.models.find_or_create_by_value('147')
trim = model.trims.find_or_create_by_value('2.0 Lusso 5d (2001 - 2005)')
values = [
 {value: '2001 (X)'},
 {value: '2001 (Y)'},
 {value: '2001 (51)'},
 {value: '2002 (51)'},
 {value: '2002 (02)'},
 {value: '2002 (52)'},
 {value: '2003 (52)'},
 {value: '2003 (03)'},
 {value: '2003 (53)'},
 {value: '2004 (53)'},
 {value: '2004 (04)'},
 {value: '2004 (54)'},
 {value: '2005 (54)'},
 {value: '2005 (05)'}
]
values.each do |item|
  trim.model_years.where(item).first_or_create
end

如果您使用_by_value,ActiveRecord 需要一个 ... 值!不是哈希:)

【讨论】:

  • 感谢您的更新 - 虽然有趣的是问题在于 model_years 值(由使用 first_or_create 的底部循环创建)...其他问题是否会产生连锁反应?
  • 好吧,如果你每次都创建一个新的装饰而不是找到它,那么你会重新创建所有的 model_years,因为它是一个不同的装饰。你再试一次吗?还在重复吗?
  • 是的,刚刚又试了一次,我仍然得到重复。我已将问题中的代码更新为我的新代码,从而避免使用任何 find_or_create_by 语句,以避免混淆。
  • 奇怪,试试这个吧? ModelYear.where(item.merge({trim_id: trim.id }))。还要尝试每次记录 tirm id,以便仔细检查这不是因为您有重复的修剪
  • 我突然想到,这段代码的整体方法可能是错误的;它本质上是在寻找已经存在的车型年份,因为没有,所以它总是添加一个新的 model_year,而不仅仅是与具有相同值的现有车型年份的关联。
猜你喜欢
  • 2017-01-08
  • 2013-06-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-20
  • 2021-11-25
  • 2016-07-03
  • 2020-02-14
  • 1970-01-01
相关资源
最近更新 更多