Estou usando Ruby on Rails 3.2.2 e gostaria de saber se o seguinte é uma maneira "adequada" / "correta" / "certa" de substituir um método setter para um atributo my class.
attr_accessible :attribute_name
def attribute_name=(value)
... # Some custom operation.
self[:attribute_name] = value
end
O código acima parece funcionar como esperado. No entanto, gostaria de saber se, usando o código acima, no futuro terei problemas ou, pelo menos, quais problemas "devo esperar" / "podem acontecer" com o Ruby on Rails . Se esse não é o caminho certo para substituir um método setter, qual é o caminho certo?
Nota : Se eu usar o código
attr_accessible :attribute_name
def attribute_name=(value)
... # Some custom operation.
self.attribute_name = value
end
Estou tendo o erro a seguir:
SystemStackError (stack level too deep):
actionpack (3.2.2) lib/action_dispatch/middleware/reloader.rb:70
Respostas:
==================================================== ========================= Atualização: 19 de julho de 2017
Agora a documentação do Rails também está sugerindo o uso
super
assim:==================================================== =========================
Resposta original
Se você deseja substituir os métodos setter para colunas de uma tabela enquanto acessa através de modelos, esta é a maneira de fazê-lo.
Consulte Substituindo acessadores padrão na documentação do Rails.
Portanto, seu primeiro método é a maneira correta de substituir os configuradores de coluna em Models of Ruby on Rails. Esses acessadores já são fornecidos pelo Rails para acessar as colunas da tabela como atributos do modelo. Isso é o que chamamos de mapeamento ActiveRecord ORM.
Lembre-se também de que a
attr_accessible
parte superior do modelo não tem nada a ver com os acessadores. Possui uma funcionalidade completamente diferente (consulte esta pergunta )Porém, no Ruby puro, se você definiu acessadores para uma classe e deseja substituir o setter, deve usar a variável de instância como esta:
Isso será mais fácil de entender quando você souber o que
attr_accessor
faz. O códigoattr_accessor :name
é equivalente a esses dois métodos (getter e setter)Além disso, seu segundo método falha porque causa um loop infinito quando você está chamando o mesmo método
attribute_name=
dentro desse método.fonte
attr_accessible
uma vez que não está mais lá, e ele deve funcionarsuper
?super
talvez não funcionem. Mas, parece que não é o caso. Acabei de verificar e funciona para mim. Além disso, esta pergunta é a mesmawrite_attribute
. As conversões serão ignoradas. Esteja ciente de quewrite_attribute
ignorará as conversões de fuso horário com datas, que quase sempre serão indesejadas.Use a
super
palavra-chave:Por outro lado, para substituir o leitor:
fonte
Nos trilhos 4
digamos que você tenha o atributo idade na sua tabela
Nota: Para novos usuários no Rails 4, você não precisa especificar attr_accessible no modelo. Em vez disso, você deve listar seus atributos no nível do controlador usando o método de permissão .
fonte
Eu descobri que (pelo menos para coleções de relacionamento ActiveRecord) o seguinte padrão funciona:
(Isso pega as 3 primeiras entradas não duplicadas na matriz passada).
fonte
Usando
attr_writer
para substituir o configurador attr_writer: attribute_namefonte