Eu li algumas coisas sobre como estender a classe ActiveRecord: Base para que meus modelos tenham alguns métodos especiais. Qual é a maneira mais fácil de estendê-lo (tutorial passo a passo)?
ruby-on-rails
extend
rails-activerecord
xpepermint
fonte
fonte
Respostas:
Existem várias abordagens:
Usando ActiveSupport :: Concern (preferencial)
Leia a documentação do ActiveSupport :: Concern para obter mais detalhes.
Crie um arquivo chamado
active_record_extension.rb
nolib
diretórioCrie um arquivo no
config/initializers
diretório chamadoextensions.rb
e adicione a seguinte linha ao arquivo:Herança (Preferida)
Consulte a resposta de Toby .
Remendo de macaco (deve ser evitado)
Crie um arquivo no
config/initializers
diretório chamadoactive_record_monkey_patch.rb
.A famosa citação sobre expressões regulares de Jamie Zawinski pode ser redefinida para ilustrar os problemas associados à correção de macacos.
O patch dos macacos é fácil e rápido. Mas, o tempo e o esforço economizados são sempre extraídos de volta em algum momento no futuro; com juros compostos. Hoje em dia, limitei a aplicação de patches de macaco para prototipar rapidamente uma solução no console do rails.
fonte
require
o arquivo no final deenvironment.rb
. Eu adicionei esta etapa extra à minha resposta.ImprovedActiveRecord
e herdá-lo; ao usarmodule
, você está atualizando a definição da classe em questão. Eu costumava usar herança (causa de anos de experiência em Java / C ++). Hoje em dia eu uso principalmente módulos.Refinements
que aborda a maioria dos problemas relacionados à aplicação de patches de macaco ( yehudakatz.com/2010/11/30/ruby-2-0-refinements-in-practice ). Às vezes, um recurso existe apenas para obrigá-lo a tentar o destino. E às vezes você faz.Você pode apenas estender a classe e simplesmente usar herança.
fonte
abstract_models
. Onde devo colocá-lo?self.abstract_class = true
ao seuAbstractModel
. O Rails agora reconhecerá o modelo como um modelo abstrato.AbstractModel
no banco de dados. Quem sabia que um simples levantador me ajudaria a secar as coisas! (Eu estava começando a me encolher ... era ruim). Obrigado Toby e Harish!Você também pode usar
ActiveSupport::Concern
e ser mais idiomático do núcleo do Rails, como:[Editar] após o comentário de @daniel
Todos os seus modelos terão o método
foo
incluído como método de instância e os métodosClassMethods
incluídos como métodos de classe. Por exemplo, em umFooBar < ActiveRecord::Base
você terá:FooBar.bar
eFooBar#foo
http://api.rubyonrails.org/classes/ActiveSupport/Concern.html
fonte
InstanceMethods
está obsoleto desde o Rails 3.2, basta colocar seus métodos no corpo do módulo.ActiveRecord::Base.send(:include, MyExtension)
um inicializador e, em seguida, isso funcionou para mim. Rails 4.1.9Com o Rails 4, o conceito de usar preocupações para modularizar e secar seus modelos tem sido destaque.
As preocupações basicamente permitem agrupar código semelhante de um modelo ou entre vários modelos em um único módulo e, em seguida, usar esse módulo nos modelos. Aqui está um exemplo:
Considere um modelo de artigo, um modelo de evento e um modelo de comentário. Um artigo ou evento tem muitos comentários. Um comentário pertence ao artigo ou evento.
Tradicionalmente, os modelos podem ser assim:
Modelo de comentário:
Artigo Modelo:
Modelo de Evento
Como podemos observar, há um pedaço significativo de código comum ao modelo de eventos e artigos. Usando preocupações, podemos extrair esse código comum em um módulo separado.
Para isso, crie um arquivo commentable.rb em app / model / preocupações.
E agora seus modelos ficam assim:
Modelo de comentário:
Artigo Modelo:
Modelo de Evento
Um ponto que gostaria de destacar ao usar o Concerns é que o Concerns deve ser usado para agrupamentos 'baseados em domínio' em vez de agrupamentos 'técnicos'. Por exemplo, um agrupamento de domínio é como 'Comentável', 'Taggable' etc. Um agrupamento técnico será como 'FinderMethods', 'ValidationMethods'.
Aqui está um link para um post que achei muito útil para entender as preocupações nos modelos.
Espero que a redação ajude :)
fonte
Passo 1
Passo 2
etapa 3
fonte
O Rails 5 fornece um mecanismo interno para extensão
ActiveRecord::Base
.Isso é conseguido fornecendo uma camada adicional:
e todos os modelos herdam desse:
Veja, por exemplo, este post do blog .
fonte
Apenas para adicionar a este tópico, passei um tempo tentando descobrir como testar essas extensões (segui o
ActiveSupport::Concern
caminho).Veja como eu configuro um modelo para testar minhas extensões.
fonte
Com o Rails 5, todos os modelos são herdados do ApplicationRecord e oferecem uma boa maneira de incluir ou estender outras bibliotecas de extensão.
Suponha que o módulo de métodos especiais precise estar disponível em todos os modelos, inclua-o no arquivo application_record.rb. Se quisermos aplicar isso a um conjunto específico de modelos, inclua-o nas respectivas classes de modelo.
Se você quiser ter os métodos definidos no módulo como métodos de classe, estenda o módulo para ApplicationRecord.
Espero que ajude os outros!
fonte
eu tenho
em um inicializador
Para um módulo como abaixo
fonte