如何create_or_update一个独特的现有验证

时间:2017-03-01 22:58:27

标签: ruby ruby-on-rails-4 update-attributes

为什么我无法更新属性,因为我没有更新唯一字段?

urlmd5和url都具有唯一性验证:

validates :url, presence: true, uniqueness: true
validates :urlmd5, presence: true, uniqueness: true

本作品:

    ParserUrl.where(urlmd5: p[:urlmd5]).first_or_initialize.update_attributes!(
        user_id: item.user_id, parser_id: item.parser_id
    )

这不起作用:

    ParserUrl.where(url: p[:url], urlmd5:p[:urlmd5]).first_or_initialize.update_attributes!(
        user_id: item.user_id, parser_id: item.parser_id
    )

I got error 'unable to update existing record'...

是first_or_initialize.update_attributes!处理这个的正确方法?

1 个答案:

答案 0 :(得分:0)

问题在于我没有将唯一值传递给first_or_initialize,因此在创建新实例时由于缺乏唯一性,存在或两者都失败。

您需要将唯一值传递给first_or_initialize:

ParserUrl.where(urlmd5: p[:urlmd5]).
    first_or_initialize(url: p[:url].to_s, urlmd5: p[:urlmd5]).
    update_attributes!(user_id: item.user_id, parser_id: item.parser_id)

Rails 4中的另一种方式:

1)只打了一次DB:

ParserUrl.find_or_initialize_by(url: p[:url].to_s, urlmd5: p[:urlmd5]).
    update_attributes!(user_id: item.user_id, parser_id: item.parser_id)

2)这将击中DB两次(不可取):

ParserUrl.find_or_create_by!(url: p[:url].to_s, urlmd5: p[:urlmd5]).
    update_attributes!(user_id: item.user_id, parser_id: item.parser_id)