Come posso sovrascrivere un metodo getter in un modello ActiveRecord?


98

Sto cercando di sovrascrivere un metodo getter per un modello ActiveRecord. Ho un attributo chiamato namenel modello Categorye mi piacerebbe poter fare qualcosa del genere:

def name
  name_trans || name
end

Se l' name_transattributo non è nullo, restituiscilo, altrimenti restituisci l' nameattributo. Come lo farei?

Questo dovrebbe quindi essere chiamato normalmente in questo modo:

@category.name

Risposte:



98

Aggiornamento: il metodo preferito secondo la Rails Style Guide è usare al self[:name]posto di read_attributee write_attribute. Ti incoraggio a saltare la mia risposta e preferire invece questa .


Puoi farlo esattamente così, tranne che devi usare read_attributeper recuperare effettivamente il valore dell'attributo name ed evitare la chiamata ricorsiva al namemetodo:

def name 
  name_trans || read_attribute(:name)
end

2
Qualsiasi idea del perché Rubocop preferisce self[:name]over read_attribute[:name]?
Zack Xu

18

Vorrei aggiungere un'altra opzione per sovrascrivere il metodo getter, che è semplicemente : super.

def name
  name_trans || super
end

questo funziona non solo sul metodo getter degli attributi, ma anche sui metodi getter delle associazioni ,


1
Questo è ciò che le guide Rails raccomandano attualmente, per getter E setter: api.rubyonrails.org/classes/ActiveRecord/…
sandre89

5

Sovrascrivere il getter e usare read_attributenon funziona per le associazioni, ma puoi usare alias_method_chaininvece.

def name_with_override
  name_trans || name_without_override
end

alias_method_chain :name, :override

Puoi fare un buon esempio ...?
Arup Rakshit

Bene. Ho appena visto il doco . Ora, se chiamo namel'oggetto modello, quale sarà chiamato - name_with_overrideo name_without_override?
Arup Rakshit

1
nameora chiamerà name_with_override. Se vuoi chiamare il metodo originale per qualche motivo, puoi chiamare name_without_override.
Patrick Oscity

O
capisco

2

Se utilizzi attributi del negozio come questo

store :settings, accessors: [:volume_adjustment] 

o usando gemme come hstore_accessor gem link

Quindi hai finito per usare il storemetodo sul modello, quindi per sovrascrivere quei metodi che non puoi usare self.read_attribute, devi usare invece in superquesto modo:

def partner_percentage
  super.to_i || 10
end

0

Se qualcuno vuole aggiornare il valore dopo name_transnel metodo getter, puoi usare self [: name] =.

def name
  self[:name] = name_trans || self[:name]
  # don't do this, it will cause endless loop
  # update(name: name_trans)
end

0

Puoi usare il metodo read_attribute di Rails. Documenti di Rails


anche se questo collegamento potrebbe rispondere alla domanda, le risposte solo al collegamento non sono consentite su SO, per favore aggiungi un po 'di contesto alla tua risposta da cosa c'è dietro quel collegamento. Grazie! :)
AJT82
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.