在 Rails 3 中 find_or_create_by 并更新以创建记录 [英] find_or_create_by in Rails 3 and updating for creating records

查看:20
本文介绍了在 Rails 3 中 find_or_create_by 并更新以创建记录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不确定我是否应该以这种方式更新记录,或者我是否遗漏了什么.

I'm not sure if I should be updating records this way or if I'm missing something.

我有一个包含 5 列(不包括时间戳和 ID)的表,其中 3 列是不同的,2 列将被更新.我将找到或创建的 3 个不同是 room_id、date 和 source.其他 2 个是价格和可用的位置(这些变化每小时、每天等)

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.

另外,像这样进行 find_and_create_by 有什么缺点吗?

Also, is there any downside to do a find_and_create_by like this?

谢谢

  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

推荐答案

这里有两种方法.

首先你可以用你需要的确切方法扩展Available:

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

使用

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 魔法为 ActiveRecord 创建 update_or_create_by... 方法:

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

这篇关于在 Rails 3 中 find_or_create_by 并更新以创建记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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