Так что я выяснил это сам. На самом деле это довольно простая, но мощная концепция. Это связано с повторным использованием кода, как в примере ниже. По сути, идея состоит в том, чтобы извлечь общие и / или контекстно-специфичные куски кода, чтобы очистить модели и избежать их слишком толстого и грязного.
В качестве примера я приведу один известный шаблон 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
Таким образом, следуя примеру Product, вы можете добавить Taggable для любого класса и поделиться его функциональностью.
Это довольно хорошо объясняется DHH :
В Rails 4 мы собираемся пригласить программистов использовать задачи с каталогами app / models / беспокойства и app / controllers / беспокойства по умолчанию, которые автоматически являются частью пути загрузки. Вместе с оберткой ActiveSupport :: Concern этой поддержки достаточно, чтобы этот легкий механизм факторинга сиял.
Я читал об использовании проблем с моделями для определения размеров кожи, а также для сушки ваших кодов моделей. Вот объяснение с примерами:
1) СУШКА кодов моделей
Рассмотрим модель Article, модель Event и модель Comment. Статья или событие имеет много комментариев. Комментарий относится к статье или событию.
Традиционно модели могут выглядеть так:
Модель комментария:
Модель статьи:
Модель события
Как мы можем заметить, существует значительный фрагмент кода, общий для Event и Article. Используя проблемы, мы можем извлечь этот общий код в отдельный модуль Commentable.
Для этого создайте файл commentable.rb в app / models / Concers.
И теперь ваши модели выглядят так:
Модель комментария:
Модель статьи:
Модель события:
2) Модели жира для кожи.
Рассмотрим модель событий. Событие имеет много посетителей и комментариев.
Как правило, модель события может выглядеть так
Модели со многими ассоциациями и в противном случае имеют тенденцию накапливать все больше и больше кода и становятся неуправляемыми. Озабоченность предоставляет способ облагораживания жировых модулей, делая их более модульными и простыми для понимания.
Вышеприведенная модель может быть реорганизована с использованием следующих проблем: Создайте
attendable.rb
иcommentable.rb
файл папке app / models / беспокойства / событияattendable.rb
commentable.rb
И теперь, используя проблемы, ваша модель событий сводится к
* При использовании проблем целесообразно использовать групповую, а не техническую группировку. Группировка на основе доменов похожа на «Commentable», «Photoable», «Attendable». Техническая группировка будет означать «Методы проверки», «Методы поиска» и т. Д.
источник
def self.my_class_method
), методы экземпляра и вызовы методов и директивы в области видимости класса. Не нужноmodule ClassMethods
add_item
, например, вы ввернуты. Я помню, как думал, что Rails был сломан, когда некоторые валидаторы перестали работать, но кто-то реализовалany?
в этом проблему. Я предлагаю другое решение: используйте проблему как интерфейс на другом языке. Вместо определения функциональности он определяет ссылку на отдельный экземпляр класса, который обрабатывает эту функциональность. Тогда у вас есть более мелкие, аккуратные классы, которые делают одно ...Стоит отметить, что использование проблем считается плохой идеей для многих.
Несколько причин:
include
метод , есть целая система обработки зависимостей - слишком много сложности для чего-то, что является тривиальным старым добрым миксином Ruby.Опасения - это простой способ выстрелить себе в ногу, будьте осторожны с ними.
источник
Этот пост помог мне понять проблемы.
источник
Я чувствовал, что большинство приведенных здесь примеров демонстрируют силу,
module
а не то, как онаActiveSupport::Concern
добавляет ценностьmodule
.Пример 1: Более читаемые модули.
Так что без проблем это как типичный
module
будет.После рефакторинга с
ActiveSupport::Concern
.Вы видите, что методы экземпляра, методы класса и включенный блок менее грязны. Проблемы будут вводить их соответственно для вас. Это одно из преимуществ использования
ActiveSupport::Concern
.Пример 2: Изящная обработка зависимостей модуля.
В этом примере
Bar
модуль, которыйHost
действительно нужен. Но так какBar
имеет зависимостьFoo
отHost
класса, нужноinclude Foo
(но подождите, почему выHost
хотите знатьFoo
? Можно ли этого избежать?).Так что
Bar
добавляет зависимость везде, где это идет. И порядок включения здесь также имеет значение. Это добавляет много сложности / зависимости к огромной базе кода.После рефакторинга с
ActiveSupport::Concern
Теперь это выглядит просто.
Если вы думаете, почему мы не можем добавить
Foo
зависимость вBar
сам модуль? Это не сработает, посколькуmethod_injected_by_foo_to_host_klass
должно быть введено в класс, который не входитBar
вBar
сам модуль.Источник: Rails ActiveSupport :: Концерн
источник
В концерте сделайте файл filename.rb
Например, я хочу в моем приложении, где существует атрибут create_by, обновить значение на 1, а 0 для updated_by.
Если вы хотите передать аргументы в действии
после этого включите в вашу модель вот так:
источник