给定多个条目的哈希值,更新activerecord关系

时间:2013-11-21 16:52:28

标签: activerecord ruby-on-rails-4

我对Rails很陌生,所以要温柔:)

我有以下模型设置:

class User
   has_many :it_certificates, :class_name => 'UserCertificate'

class UserCertificate
   belongs_to :skill

给出以下输入(以JSON格式)

{
   "certificates":[
      { // update
         "id":1,
         "name":"Agile Web Dev 2",
         "entity":"Agile Masters!",
         "non_it":false,
         "date_items":{
            "month":10,
            "year":2012
         },
         "skill": {
            "id":57
         }
      },
      { // create
         "name":"Agile Web Dev 1",
         "entity":"Agile Masters!",
         "non_it":false,
         "date_items":{
            "month":10,
            "year":2011
         },
         "skill": {
            "id":58
         }
      }     
   ]
}

如何更新关系it_certificates的信息的最简单方法是什么?

我一直在寻找update_all但它不符合我的需求(它只更新给定字段具有相同的值)。

所以我一直在努力迭代这些记录中的每一个,然后逐个更新它们。 我的意思是挣扎,因为在我看来,当Rails的想法恰恰相反时,我有很多事情需要关注。

提前致谢!

1 个答案:

答案 0 :(得分:0)

所以,这是我现在的解决方案:

  def self.update_from_hash(data, user_id)
    self.transaction do
      data.each do |certificate|
        if certificate[:id] == nil
          # create
          if !self.create(
             :name => certificate[:name],
             :entity => certificate[:entity],
             :user_id => user_id,
             :non_it => certificate[:non_it],
             :skill_id => certificate[:skill][:id],
             :date => self.build_date_from_items(certificate[:date_items][:month], certificate[:date_items][:year])
          )
            raise ActiveRecord::Rollback
          end
        else
          # update
          if !self.update(certificate[:id], {
              :name => certificate[:name],
              :entity => certificate[:entity],
              :non_it => certificate[:non_it],
              :skill_id => certificate[:skill][:id],
              :date => self.build_date_from_items(certificate[:date_items][:month], certificate[:date_items][:year])
          })
            raise ActiveRecord::Rollback
          end
        end
      end
    end
    return true
  end

它有效,但我仍然期待更优雅的解决方案:)