ruby-on-rails – 在Rails 3中找到find_or_create_by并更新创建记录

前端之家收集整理的这篇文章主要介绍了ruby-on-rails – 在Rails 3中找到find_or_create_by并更新创建记录前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我不知道如果我应该这样更新记录,或者我错过了一些东西.

我有一个5列(不包括时间戳和id)的表,其中3列是不同的,2个将被更新.我会发现或创建的3个区别是room_id,date和source.另外2个是可用的价格和地点(这些小时,每天等)

我的问题是,我应该首先找到或创建记录,然后更新(或创建)价格和位置,或者我可以一次性完成所有操作?你可以看到我现在正在做的两种方式,我不知道它是否真的在做我期望的事情.

另外,这样做有一个find_and_create_by有什么缺点吗?

谢谢

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

解决方法

这里有两种方法.

First您可以扩展可用您需要的确切方法

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,source ) || self.new(:room_id => room_id,:bookdate => bookdate,:source => source)
  yield obj
  obj.save
end

用法

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

这很尴尬因此,为了更灵活,您可以使用method_missing magic为ActiveRecord创建update_or_create_by …方法

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,&block)
    else
      super
    end
  end
  def self.update_or_create(search,&block)
    parameters = search.split("_and_")
    params = Hash[ parameters.zip(args) ]
    obj = where(params).first || self.new(params)
    yield obj
    obj.save
    obj
  end
end

所以现在你可以使用它:

Available.update_or_create_by_id_and_source(20,"my_source") do |a|
  a.whatever = "coooool"
end

猜你在找的Ruby相关文章