Como posso substituir um método getter em um modelo ActiveRecord?


98

Estou tentando substituir um método getter para um modelo ActiveRecord. Tenho um atributo chamado nameno modelo Categorye gostaria de poder fazer algo assim:

def name
  name_trans || name
end

Se o name_transatributo não for nulo, retorne-o, caso contrário, retorne o nameatributo. Como eu faria isso?

Em seguida, deve ser chamado normalmente assim:

@category.name

Respostas:



98

Update: O método preferido de acordo com o Rails Style Guide é usar ao self[:name]invés de read_attributee write_attribute. Eu o encorajaria a pular minha resposta e preferir esta .


Você pode fazer exatamente assim, exceto que você precisa usar read_attributepara realmente buscar o valor do atributo name e evitar a chamada recursiva para o namemétodo:

def name 
  name_trans || read_attribute(:name)
end

2
Alguma idéia de por Rubocop prefere self[:name]mais read_attribute[:name]?
Zack Xu

18

Eu gostaria de adicionar outra opção para sobrescrever o método getter, que é simplesmente: super.

def name
  name_trans || super
end

isso funciona não apenas no método getter de atributos, mas também nos métodos getter de associações。


1
Isso é o que os guias do Rails recomendam atualmente, para getters E setters: api.rubyonrails.org/classes/ActiveRecord/…
sandre89

5

Substituir o getter e usar read_attributenão funciona para associações, mas você pode usar alias_method_chain.

def name_with_override
  name_trans || name_without_override
end

alias_method_chain :name, :override

Você pode dar um exemplo adequado ...?
Arup Rakshit

Bem. Acabei de ver o doco . Agora, se eu chamar nameo objeto de modelo, qual será chamado - name_with_overrideou name_without_override?
Arup Rakshit

1
nameagora vai ligar name_with_override. Se você deseja chamar o método original por algum motivo, você pode chamar name_without_override.
Patrick Oscity

O que vejo .. Obrigado por suas respostas //
Arup Rakshit

2

Se você usar atributos de loja como este

store :settings, accessors: [:volume_adjustment] 

ou usando gemas como hstore_accessor link de gema

Então você acabou usando o storemétodo no modelo, então para substituir aqueles métodos que você não pode usar self.read_attribute, você deve usar superassim:

def partner_percentage
  super.to_i || 10
end

0

Se alguém quiser atualizar o valor após o name_transmétodo getter, você pode usar 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

Você pode usar o método read_attribute do Rails. Rails docs


Embora este link possa responder à pergunta, respostas apenas de link não são permitidas no SO, por favor, adicione algum contexto à sua resposta a partir do que está por trás desse link. Obrigado! :)
AJT82 de
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.