在Rails中,更新记录或创建新记录(如果不存在)的最佳方法是什么? [英] In Rails, what is the best way to update a record or create a new one if it doesn't exist?

查看:55
本文介绍了在Rails中,更新记录或创建新记录(如果不存在)的最佳方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我为某些模型创建了一条create语句,但是无论该记录是否已存在,它都会在联接表中创建一条记录。

I have a create statement for some models, but it’s creating a record within a join table regardless of whether the record already exists.

这是我的代码的外观像这样:

Here is what my code looks like:

@user = User.find(current_user)
@event = Event.find(params[:id])
for interest in @event.interests
 @user.choices.create(:interest => interest, :score => 4)
end

问题是无论如何它都会创建记录。我希望仅在不存在任何记录的情况下创建记录;如果确实存在一条记录,我希望它采用找到的记录的属性并添加或减去1。

The problem is that it creates records no matter what. I would like it to create a record only if no record already exists; if a record does exist, I would like it to take the attribute of the found record and add or subtract 1.

我一直在寻找的东西称为 find_or_create_by 。找到记录后该怎么办?我希望它采用当前的:score 属性并添加1。

I’ve been looking around have seen something called find_or_create_by. What does this do when it finds a record? I would like it to take the current :score attribute and add 1.

是否可以找到或创建通过 id ?我不确定要找到什么属性,因为我要查看的模型是一个联接模型,该联接模型仅具有 id 外键和score属性。

Is it possible to find or create by id? I’m not sure what attribute I would find by, since the model I’m looking at is a join model which only has id foreign keys and the score attribute.

我尝试了

@user.choices.find_or_create_by_user(:user => @user.id, :interest => interest, :score => 4)

但是


未定义的方法 find_by_user

我该怎么办?

推荐答案

假设选择模型具有 user_id (与用户关联)和 interest_id (与兴趣相关联),类似这样的方法应该可以解决问题:

Assuming that the Choice model has a user_id (to associate with a user) and an interest_id (to associate with an interest), something like this should do the trick:

@user = User.find(current_user)
@event = Event.find(params[:id])

@event.interests.each do |interest|
  choice = @user.choices.find_or_initialize_by_interest_id(interest.id) do |c|
    c.score = 0 # Or whatever you want the initial value to be - 1
  end

  choice.score += 1
  choice.save!
end

一些注意事项:


  1. 您无需在 find_or _ * _ by _ * user_id 列>,因为您已经指示Rails仅获取属于 @user 选择

  2. 我正在使用 find_or_initialize_by _ * ,与 find_or_create_by _ * 基本上相同,主要区别在于初始化实际上并未创建记录。这与 Model.new 相似,而不是 Model.create

  3. 设置 c.score = 0 的块仅在记录存在的情况下才执行。

  4. choice.score + = 1 会更新记录的得分值,无论它是否存在。因此,默认分数 c.score = 0 应该是初始值减去一。

  5. 最后, choice.save!将更新记录(如果已存在)或创建已初始化的记录(如果不存在)。

  1. You don't need to include the user_id column in the find_or_*_by_*, as you've already instructed Rails to only fetch choices belonging to @user.
  2. I'm using find_or_initialize_by_*, which is essentially the same as find_or_create_by_*, with the one key difference being that initialize doesn't actually create the record. This would be similar to Model.new as opposed to Model.create.
  3. The block that sets c.score = 0 is only executed if the record does not exist.
  4. choice.score += 1 will update the score value for the record, regardless if it exists or not. Hence, the default score c.score = 0 should be the initial value minus one.
  5. Finally, choice.save! will either update the record (if it already existed) or create the initiated record (if it didn't).

这篇关于在Rails中,更新记录或创建新记录(如果不存在)的最佳方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆