find_or_create_by_id的最佳方法,但如果找到记录则更新属性(Best way to find_or_create_by_id but update the attributes if the record is found)

如果记录不存在,并且 - 如果记录确实存在 - 更新其属性,我正在寻找一种干净的方法来创建具有一组属性的记录。 我喜欢find_or_create_by_id调用中块的语法。 这是我的代码:

@categories = Highrise::DealCategory.find(:all) @categories.each do |category| puts "Category: #{category.name}" Category.find_or_create_by_id(category.id) do |c| c.name = category.name end end

这里的问题是,如果记录存在但名称已更改,则不会更新。

寻找这个问题的清洁解决方案......

I'm looking for a clean way to create a record with a set of attributes if the record does not exist and - if the record do exist - to update its attributes. I love the syntax of the block in the find_or_create_by_id call. Here's my code:

@categories = Highrise::DealCategory.find(:all) @categories.each do |category| puts "Category: #{category.name}" Category.find_or_create_by_id(category.id) do |c| c.name = category.name end end

The problem here is that if the record exists but the name has changed, it is not being updated.

Looking for a clean solution to this problem...

最满意答案

你可以编写自己的方法:

class ActiveRecord::Base def self.find_by_id_or_create(id, &block) obj = self.find_by_id( id ) || self.new yield obj obj.save end end

用法

Category.find_by_id_or_create(10) do |c| c.name = "My new name" end

当然,通过这种方式,您应该扩展method missing方法,并以与其他find_by_something方法相同的方式实现此方法。 但是为了做空,这就足够了。

You can write your own method:

class ActiveRecord::Base def self.find_by_id_or_create(id, &block) obj = self.find_by_id( id ) || self.new yield obj obj.save end end

usage

Category.find_by_id_or_create(10) do |c| c.name = "My new name" end

Of course, in this way you should extend method missing method and implement this method in the same way as others find_by_something methods. But for being short this will be enough.

更多推荐