10

Se ho un'associazione 'belongs_to' in un modello, mi piacerebbe conoscere la differenza concettuale tra la convalida un'associazione:Rails 4: Differenza tra convalida presenza sul id o associazione

class Topping < ActiveRecord::Base 
    belongs_to :pancake 
    validates :pancake, presence: true 
    ... 

e convalidare la associato id del modello:

class Topping < ActiveRecord::Base 
    belongs_to :pancake 
    validates :pancake_id, presence: true 
    ... 

motivazione:

alcuni codice che assegna una guarnizione per un pancake smesso di funzionare a un certo momento nel passato. Cambiando la convalida dall'associazione all'id 'risolto' il problema, ma mi piacerebbe conoscere la ragione più profonda del perché.

(A proposito, quando si passa nel codice il pancake era valida e nel database e il topping risposto sia .pancake e .pancake_id appropriato. Sia l'operatore spinta (pancake.toppings << topping) e assegnazione manuale e salvare (topping.pancake = pancake; topping.save) non riuscita con un pancake . mancante errore di convalida)

risposta

3

Indagare ulteriormente, ho scoperto che il validatore 'presenza' decide di 'add_on_blank':

http://apidock.com/rails/ActiveModel/Errors/add_on_blank

def add_on_blank(attributes, options = {}) 
    Array(attributes).each do |attribute| 
    value = @base.send(:read_attribute_for_validation, attribute) 
    add(attribute, :blank, options) if value.blank? 
    end 
end 

Questo fa quello che dice: aggiunge un errore di convalida se la proprietà in questione è blank?

Ciò significa che è semplicemente un controllo di esistenza. Quindi se convalidassi un id, quell'id deve esistere. Ciò significa:

topping.pancake = Pancake.new 
topping.valid? 

restituirebbe falso. Tuttavia:

topping.pancake_id = -12 
topping.valid? 

restituire true. D'altra parte, se convalidassi l'oggetto, l'esatto contrario sarebbe vero. A meno che -12 sia un indice valido, nel qual caso ActiveRecord lo caricherà automaticamente dal database alla ricezione del messaggio 'pancake'.

Passando al mio problema, ulteriori indagini hanno dimostrato che blank? delegati al empty?, e in effetti qualcuno aveva definito empty? sul pancake, restituendo vero se non ci sono condimenti.

Trovato colpevole, e qualcosa su Rails appreso.

Problemi correlati