2017-03-01 28 views
0

Warum kann ich Attribute nicht aktualisieren, da ich ein eindeutiges Feld nicht aktualisiere?So erstellen Sie eine eindeutige und aktuelle Validierung create_or_update

urlmd5 und die URL sowohl Einzigartigkeit Validierung hat:

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

Dieses Werk:

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

Dies funktioniert nicht:

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'... 

Ist first_or_initialize.update_attributes! der richtige Weg, damit umzugehen?

+0

Können Sie den vollständigen Fehler genau so eingeben, wie er angezeigt wird? Was genau ist "p" in diesem Zusammenhang? – Glyoko

+0

Ich nehme an, Sie haben einen Datensatz, der bereits den Wert p [: url] in url oder den Wert p [: urlmd5] in urlmd5, aber nicht beides hat. First_or_initialize findet also nicht die Kombination von beiden, also initialisiert man einen Datensatz mit beiden, aber die Eindeutigkeitsbedingung gilt immer noch für eines der Felder. – SteveTurczyn

+0

Könnte es sein, dass Sie nur auf BEIDEN Feldern eine Eindeutigkeit wünschen? Sie müssen Ihre Validierung ändern. 'validates: urlmd5, present: true, Eindeutigkeit: {scope:: url}' und dasselbe für die Umkehrung. – SteveTurczyn

Antwort

0

Das Problem war, dass ich keine eindeutigen Werte an first_or_initialize übergeben habe. Wenn eine neue Instanz erstellt wird, ist dies aufgrund fehlender Eindeutigkeit, Präsenz oder beides fehlgeschlagen.

Sie müssen eindeutige Werte zu übergeben 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) 

andere Art und Weise in Rails 4:

1) traf nur die DB einmal:

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) Dieser Wille triff die DB zweimal (nicht erwünscht):

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) 
Verwandte Themen