find_or_create_by在Rails 3的更新和创造纪录 [英] find_or_create_by in Rails 3 and updating for creating records
问题描述
我不知道我是否应该更新记录这样或者如果我失去了一些东西。
我有5列(不包括时间戳和id),其中3个是不同的,并且2将得到更新的表。在3个不同的,我会寻找或创造还有ROOM_ID,日期和来源。其他2是价格和使用点(这些改变每小时,每天等)
我的问题是,我应该先找到或创建记录,然后更新(或创建)的价格和斑点或者我可以做到这一切在一次?你可以看到两种方式,现在我做的,我不知道它实际上做了什么,我期待的。
此外,有没有任何缺点做这样的find_and_create_by?
感谢
私有
高清self.parse_data(PARAMS,数据)
data.beds.each做|床|
房间= Room.find_or_create_room(bed.title,则params [:ID])
#find克隆不知何故
#puts bed.nights.first.price
bed.nights.each_with_index做|晚上,指数|
可用= Available.find_or_create_by_room_id_and_bookdate_and_source(
:ROOM_ID => room.id,
:bookdate => (PARAMS [:日期] .to_date)+指数,
:源=> data.class.to_s#,
#:价格=> night.price
)
#available.price = night.price
#available.spots = night.spots
#available.save
结束
结束
下面是两种方法。
<一个href="http://stackoverflow.com/questions/5160073/best-way-to-find-or-create-by-id-but-update-the-attributes-if-the-record-is-found/5160233#5160233">First你可以扩展可用
有确切的方法,你需要:
高清self.find_or_create_by_room_id_and_bookdate_and_source(ROOM_ID,bookdate,来源和放大器;块)
OBJ = self.find_by_room_id_and_bookdate_and_source(ROOM_ID,bookdate,源)|| self.new(:ROOM_ID =&GT; ROOM_ID,:bookdate =&GT; bookdate,:源=&GT;源)
产量OBJ
obj.save
结束
用法
Available.find_or_create_by_room_id_and_bookdate_and_source(room.id,(PARAMS [:日期] .to_date)+指数,data.class.to_s)办| C |
c.price = night.price
c.spots = night.spots
结束
这是尴尬的。因此,对于更加灵活的,你可以为的ActiveRecord
创建 update_or_create_by ...
方法,使用 method_missing的
魔法:
类的ActiveRecord :: Base的
高清self.method_missing(method_id,*的args,&安培;块)
方法_ = method_id.to_s
如果方法_ =〜/^update_or_create_by_(.+)$/
update_or_create($ 1,*的args,&安培;块)
其他
超
结束
结束
高清self.update_or_create(搜索,*的args,&安培;块)
参数= search.split(_ and_)
PARAMS =哈希[parameters.zip(参数)]
OBJ =其中(PARAMS)。首先|| self.new(PARAMS)
产量OBJ
obj.save
OBJ
结束
结束
所以,现在你可以使用它:
Available.update_or_create_by_id_and_source(20,my_source)做| A |
a.whatever =coooool
结束
I'm not sure if I should be updating records this way or if I'm missing something.
I have a table with 5 columns (not including timestamps and id) 3 of which are distinct, and 2 which will get updated. The 3 distinct which I will find or create by are room_id, date, and source. The other 2 are price and spots available (these change hourly, daily etc.)
My question is, should I first find or create the record, then update (or create) the price and spots or can I do it all at once? You can see the two ways I'm doing it now, and I'm not sure if its actually doing what I'm expecting.
Also, is there any downside to do a find_and_create_by like this?
Thanks
private
def self.parse_data(params,data)
data.beds.each do |bed|
room = Room.find_or_create_room(bed.title, params[:id])
#find clones somehow
#puts bed.nights.first.price
bed.nights.each_with_index do |night,index|
available = Available.find_or_create_by_room_id_and_bookdate_and_source(
:room_id => room.id,
:bookdate => (params[:date].to_date)+index,
:source => data.class.to_s#,
#:price => night.price
)
#available.price = night.price
#available.spots = night.spots
#available.save
end
end
Here is two approaches.
First you can extend Available
with exact method you need:
def self.find_or_create_by_room_id_and_bookdate_and_source(room_id, bookdate, source, &block)
obj = self.find_by_room_id_and_bookdate_and_source( room_id, bookdate, source ) || self.new(:room_id => room_id, :bookdate => bookdate, :source => source)
yield obj
obj.save
end
usage
Available.find_or_create_by_room_id_and_bookdate_and_source(room.id, (params[:date].to_date)+index, data.class.to_s) do |c|
c.price = night.price
c.spots = night.spots
end
This is awkward. So for being more flexible you can create update_or_create_by...
method for ActiveRecord
using method_missing
magic:
class ActiveRecord::Base
def self.method_missing(method_id, *args, &block)
method_name = method_id.to_s
if method_name =~ /^update_or_create_by_(.+)$/
update_or_create($1, *args, &block)
else
super
end
end
def self.update_or_create(search, *args, &block)
parameters = search.split("_and_")
params = Hash[ parameters.zip(args) ]
obj = where(params).first || self.new(params)
yield obj
obj.save
obj
end
end
So now you can use it:
Available.update_or_create_by_id_and_source(20, "my_source") do |a|
a.whatever = "coooool"
end
这篇关于find_or_create_by在Rails 3的更新和创造纪录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!