【问题标题】:How to create_or_update a unique and present validation如何 create_or_update 唯一且当前的验证
【发布时间】:2017-03-01 22:58:26
【问题描述】:

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

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!正确的处理方法是什么?

【问题讨论】:

  • 你能给出完整的错误信息吗?在这种情况下,p 到底是什么?
  • 我猜你有一条记录,它已经在 url 中获得了 p[:url] 值或在 urlmd5 中获得了 p[:urlmd5] 值,但不是两者都有。所以 first_or_initialize 并没有找到两者的组合,所以初始化记录也是如此,但唯一性约束仍然适用于其中一个字段。
  • 您是否希望仅在两个字段的组合上具有唯一性?您需要更改验证。 validates :urlmd5, presence: true, uniqueness: {scope: :url} 反之亦然。
  • @SteveTurczyn 看看我的回答

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


【解决方案1】:

问题是我没有将唯一值传递给 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) 这将命中数据库两次(不可取):

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)

【讨论】:

    猜你喜欢
    • 2013-06-03
    • 2012-11-15
    • 2018-07-06
    • 2017-10-04
    • 2016-08-18
    • 1970-01-01
    • 1970-01-01
    • 2022-11-15
    • 1970-01-01
    相关资源
    最近更新 更多