Capire Ruby on Rails ActiveRecord accessor modello
-
22-09-2019 - |
Domanda
Il mio modello, "DataFile", ha un sacco di campi che mi piacerebbe impostare dall'esterno del modello, per esempio.
file = DataFile.new file.owner = 123
Ora, per quanto ne so, avrei dovuto effettuare un "attr_accessor: campo" nel mio modello, per ogni campo che mi piacerebbe modificare dall'esterno. Tuttavia, il codice sopra funziona bene senza avere attr_accessors definiti, impostando il campo proprietario a 123. Perché?
Mi aspettavo di ottenere un "metodo non definito" errore o qualcosa del genere.
Soluzione
A causa ORM Rails utilizza il modello di ActiveRecord, due metodi vengono creati automaticamente per ogni colonna del database associato a quel tavolo: columnname e columnname = . Questo avviene "automaticamente" a seguito del modello eredita da ActiveRecord :: Base. Questi metodi sono definiti utilizzando strutture metaprogrammazione di rubino e vengono creati in modo dinamico al momento della creazione della classe.
Per ulteriori informazioni come esattamente quello che sta succedendo, vorrei dare un'occhiata alla fonte Rails. Tuttavia, quanto sopra è probabilmente sufficiente per darvi una chiara visione di ciò che sta accadendo.
Altri suggerimenti
Drew e Zepplock capito bene, ma mi limiterò a aggiungere un'altra cosa. Le funzioni di accesso che Rails (in realtà, ActiveRecord) crea per i campi di database non sono di accesso di Ruby, e se si utilizza lo script / console vedrete che il proprietario non è una variabile del file oggetto istanza.
E 'probabile che non avevo mai notato questo fino a quando ci si avventura lontano dalle funzioni di accesso standard e tenta di manipolare @owner all'interno di un metodo in archivio. Se stai imparando Rubino allo stesso tempo si sta imparando Rails (che è quello che ho fatto io), è probabile che si imbatterà in questo a un certo punto. Questa è la ragione per cui è necessario scrivere:
class MyClass < ActiveRecord::Base
def invalidate_owner
self.owner = owner << " no longer owns this"
save
end
end
anziché
class MyClass < ActiveRecord::Base
def invalidate_owner
self.owner << " no longer owns this"
save
end
end
Molto probabilmente "proprietario" è parte del tuo modello di database. Le funzioni di accesso per i campi del database sono generati automaticamente per voi.