Então eu descobri sozinho. Na verdade, é um conceito bastante simples, mas poderoso. Tem a ver com a reutilização de código, como no exemplo abaixo. Basicamente, a idéia é extrair pedaços de código comuns e / ou específicos do contexto para limpar os modelos e evitar que fiquem muito gordos e sujos.
Como exemplo, vou colocar um padrão bem conhecido, o padrão taggable:
# app/models/product.rb
class Product
include Taggable
...
end
# app/models/concerns/taggable.rb
# notice that the file name has to match the module name
# (applying Rails conventions for autoloading)
module Taggable
extend ActiveSupport::Concern
included do
has_many :taggings, as: :taggable
has_many :tags, through: :taggings
class_attribute :tag_limit
end
def tags_string
tags.map(&:name).join(', ')
end
def tags_string=(tag_string)
tag_names = tag_string.to_s.split(', ')
tag_names.each do |tag_name|
tags.build(name: tag_name)
end
end
# methods defined here are going to extend the class, not the instance of it
module ClassMethods
def tag_limit(value)
self.tag_limit_value = value
end
end
end
Portanto, seguindo a amostra do produto, você pode adicionar o Taggable a qualquer classe que desejar e compartilhar sua funcionalidade.
Isso é muito bem explicado pelo DHH :
No Rails 4, convidamos os programadores a usar preocupações com os diretórios padrão app / models / preocupações e app / controllers / preocupações que fazem parte automaticamente do caminho de carregamento. Juntamente com o invólucro ActiveSupport :: Concern, é apenas o suporte suficiente para fazer brilhar esse mecanismo leve de fatoração.
Eu tenho lido sobre o uso de preocupações com modelos para modelar modelos de gordura, bem como secar os códigos de seus modelos. Aqui está uma explicação com exemplos:
1) SECAGEM de códigos de modelo
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 Evento e ao Artigo. Usando preocupações, podemos extrair esse código comum em um módulo separado.
Para isso, crie um arquivo commentable.rb em app / models / preocupações.
E agora seus modelos ficam assim:
Modelo de comentário:
Artigo Modelo:
Modelo de Evento:
2) Modelos de gordura que desnaturam a pele.
Considere um modelo de evento. Um evento tem muitos participantes e comentários.
Normalmente, o modelo de evento pode ter esta aparência
Modelos com muitas associações e de outra forma tendem a acumular cada vez mais códigos e se tornam incontroláveis. As preocupações fornecem uma maneira de reduzir o tamanho dos módulos de gordura, tornando-os mais modulares e fáceis de entender.
O modelo acima pode ser refatorado usando as preocupações conforme abaixo: Crie um arquivo
attendable.rb
ecommentable.rb
na pasta app / models / preocupações / eventoAttable.rb
commentable.rb
E agora, usando o Preocupações, seu modelo de evento se reduz a
* Enquanto estiver usando preocupações, é aconselhável optar pelo agrupamento baseado em 'domínio' em vez de agrupamento 'técnico'. O agrupamento baseado em domínio é como 'Comentável', 'Fotoable', 'Attendable'. Agrupamento técnico significa 'ValidationMethods', 'FinderMethods' etc.
fonte
def self.my_class_method
), métodos de instância e chamadas e diretrizes de método no escopo da classe. Não há necessidade demodule ClassMethods
add_item
, por exemplo, você está ferrado. Lembro-me de pensar que o Rails estava quebrado quando alguns validadores pararam de funcionar, mas alguém havia implementadoany?
uma preocupação. Proponho uma solução diferente: use a preocupação como uma interface em um idioma diferente. Em vez de definir a funcionalidade, define a referência a uma instância de classe separada que lida com essa funcionalidade. Então você tem menores, as classes mais puro que fazer uma coisa ...Vale ressaltar que o uso de preocupações é considerado ruim por muitos.
Algumas razões:
include
método de correção , existe todo um sistema de manipulação de dependências - muita complexidade para algo que é trivial e bom e velho padrão de mixagem Ruby.As preocupações são uma maneira fácil de dar um tiro na perna, tenha cuidado com elas.
fonte
Este post me ajudou a entender as preocupações.
fonte
Senti que a maioria dos exemplos aqui demonstrou o poder
module
e não comoActiveSupport::Concern
agrega valor aomodule
.Exemplo 1: Módulos mais legíveis.
Portanto, sem preocupações, isso
module
será típico .Após refatorar com
ActiveSupport::Concern
.Você vê métodos de instância, métodos de classe e bloco incluído são menos confusos. As preocupações os injetarão adequadamente para você. Essa é uma vantagem do uso
ActiveSupport::Concern
.Exemplo 2: Manipule as dependências do módulo normalmente.
Neste exemplo
Bar
é o módulo queHost
realmente precisa. Mas como aBar
dependênciaFoo
daHost
classe tem que serinclude Foo
(mas espere, por que vocêHost
quer saberFoo
? Isso pode ser evitado?).Então,
Bar
adiciona dependência aonde quer que vá. E ordem de inclusão também importa aqui. Isso adiciona muita complexidade / dependência à enorme base de código.Após refatorar com
ActiveSupport::Concern
Agora parece simples.
Se você está pensando, por que não podemos adicionar
Foo
dependência noBar
próprio módulo? Isso não funcionará, poismethod_injected_by_foo_to_host_klass
precisa ser injetado em uma classe queBar
não está incluída noBar
próprio módulo.Fonte: Rails ActiveSupport :: Concern
fonte
Em caso de preocupação, faça o arquivo filename.rb
Por exemplo, eu quero no meu aplicativo onde o atributo create_by existe atualizar o valor lá por 1 e 0 para updated_by
Se você deseja passar argumentos em ação
depois disso, inclua no seu modelo assim:
fonte