Pull to refresh

Comments 12

В Rails 4 встроенно ещё одно удобное средство выделения общего поведения из разных моделей: Concerns
На самом деле
Concerns были в Rails уже давно, но только в четвёртой версии для них автоматически создаётся директория при вызове rails new. Поэтому-то все про них и узнали.

У меня, например, многие объекты (вроде имён и названий) имели двойной набор атрибутов для двух языков и флаг родного языка. Общее поведение — получение значения на языке оригинала и транслитерированное на другой — оказалось очень удобно выделить именно таким образом.

P.S.: Понимаю некоторую кривизну такого решения в свете потенциальной многоязычности, но здесь языков принципиально ровно два
P.P.S.: За статью — спасибо!
Большое спасибо!

Насчет двойных атрибутов — мне кажется немного некрасиво и избыточно, по вашему описанию нашел вот такой gem, вроде бы делает именно так, используя локали.

Насчет консернов автор оригинальной статьи высказывается довольно негативно — “Any application with an app/concerns directory is concerning.” (какая то игра слов, что то вроде «Любое приложение с консернами — подозрительно»). Я считаю, что в mixin-ы и concern-ы стоит убирать логику, которая в общем то от модели не зависит или зависит слабо, и при этом много где используется (например как в джеме Enumerize)
Не совсем так: локаль не глобальная, а у разных записей — разная. Грубо говоря, у немца оригинальное имя отображается первым, а транслитерированное в скобках, а у русского — наоборот.

С globalize3 получится что-то в духе Post.with_translations(Post.rus? ? 'ru' : 'en'), тоже костылевато…
Да, действительно, задачка интересная
Концерны это фантастически удобно, если вам нужно переопределять модель.

К пример, если джем с моделью User. В простом случае он может состоять из одной только строки:
include UserConcerns::Base

У вас есть приложение, которе использует этот джем. И на уровне приложения потребовалось добавить в User на дополнительную логику.
Вы далете концерн и добавляете инишиалайзер с его подключением к User:
User.send(:include, CustomProjectExtension).

Кроме того, Concern разруливает подключение модулей к модулям, очень удобно.
BUG
 if BCrypt::Password.new(@user.password_digest) == unencrypted_password
      @user
    else
      false
    end

а должно быть так
 if BCrypt::Password.new(unencrypted_password) == @user.password_digest
      @user
    else
      false
    end


View objects
для этого отлично подходит draper gem. github.com/drapergem/draper
Когда сложность приложения переваливает за определенную грань, то паттерн активных записей становится небольшим злом, которое сидит у вас в самом центре всего и все, что с этим можно сделать — это что-нибудь накостылить. Решением очевидно является выбор более сложных комплексных подходов, например, DDD.

На практике же конечно сменить в распухлом приложении слой абстракции данных на что-то кардинально иное может быть очень сложно, и это не задача штатного разработчика, а компетенция менеджеров проекта и техлидов.
Ну это понятно :) но вы слишком сказали очевидное, и не забывайте что AR это тот же вид ORM, только с целью на таблицы и БД, если нужен ORM с целью на DDD то вам нужно хибернейт или доктрину например (в других fw тоже есть). Но AR позволяет тоже очень много решать проблем, в общем у всего свои дробеки. Кстати, впринципе хоть AR и нарушает правило PI в DDD, но неплохо устраняет impedance mismatch (в ORM с целью на DDD вы делаете все в xml-файлах, маппинг entity на infrastructure layer БД). Даже в конце книги Джимми Нильсона есть про то что entity может быть AR-model, хотя да не совсем DDD :D
Sign up to leave a comment.

Articles

Change theme settings