Perché il attr_accessor clobber le variabili esistenti in questo modello in Ruby on Rails?

StackOverflow https://stackoverflow.com/questions/1448414

  •  11-09-2019
  •  | 
  •  

Domanda

Sono stato morso da questo di recente, e che sarebbe stato utile sapere esattamente cosa sta succedendo per rendere questo accada, in modo che altri evitare questo errore.

Ho un modello d'uso, con uno schema in questo modo:

create_table "users", :force => true do |t|
    t.string   "user_name"
    t.string   "first_name"
    t.string   "last_name"
    t.string   "email"
    t.string   "location"
    t.string   "town"
    t.string   "country"
    t.string   "postcode"
    t.boolean  "newsletter"

Nel user.rb di classe, ho un attr_accessor per tre metodi:

class User < ActiveRecord::Base

# lots of code

  attr_protected :admin, :active

# relevant accessor methods

  attr_accessor :town, :postcode, :country 

end

Ora, nel mio controller utente, se ho il seguente metodo:

def create
    @user = User.new params[:user]
end

Quando quando cerco di creare un nuovo utente con il contenuto in questo params hash:

  --- !map:HashWithIndifferentAccess 
  # other values
  country: United Kingdom
  dob(1i): "1985"
  dob(2i): "9"
  dob(3i): "19"
  town: london

L'oggetto restituito contiene stringhe vuote per i valori country, town e NPA postcode, in questo modo.

(rdb:53) y user1
--- !ruby/object:User 
attributes: 
  # lots of attributes that aren't relevant for this example, and are filled in okay
  postcode: 
  country: 
  town: 

Vi posso dire che i metodi attr_accessor sono clobbering metodi di accesso esistenti Active Record, perché quando li tiro fuori tutto funziona benissimo, quindi la soluzione è abbastanza semplice -. Basta portarli fuori

Ma cosa esattamente sta succedendo quando qui?

sto cercando qui in rotaie documentazione API per Active Record , e qui in propri documenti di Ruby su attr_accessor , ma io sono ancora un po 'confusa su come attr_accessor sta rompendo le cose qui

.

Qualsiasi in grado di far luce per fermare qualche altra povera anima di infrangere questo?

È stato utile?

Soluzione

Quando si aggiunge un attr_accessor ad una classe, definisce due metodi su di esso, ad esempio, Utente # codice postale e l'utente # Cap =.

Se il nome della funzione di accesso è pari a un nome di un attributo di modello, le cose si rompono (se non stai attento). Quando si assegna attributi al modello, l'utente # Cap = si chiama e nel tuo caso non si fa nulla, tranne

@postcode = value

Quindi il valore appena viene memorizzato in una variabile di istanza e non appare nella attributi hash.

considerando che in uno scenario normale (senza una funzione di accesso) questo sarebbe andato a method_missing ed eventualmente innescare qualcosa di simile

write_attribute(:postcode, value)

E poi sembrerebbe negli attributi del vostro modello. Spero che abbia un senso.

Altri suggerimenti

Perché in primo luogo che si sta utilizzando attr_accessor :town, :postcode, :country? Attivo Record ha metodi setter / getter per voi. Basta inserire quella linea, le cose dovrebbero funzionare.

Si potrebbe desiderare di utilizzare attr_accessible su modelli ActiveRecord per consentire di massa-assegnazione di attributi. Non è necessario attr_accessor come getter / setter sono già definiti per gli attributi del modello.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top