Как правильно использовать базовую область в Rails - PullRequest
0 голосов
/ 29 мая 2018

У меня есть две модели, которые разделяют поведение.И Post, и Comment могут иметь реакции.

# ./app/models/post.rb
class Post < ApplicationRecord
  has_many :reactions, as: :reactionable
end

# ./app/models/comment.rb
class Comment < ApplicationRecord
  has_many :reactions, as: :reactionable
end

Когда я их украшаю, я получаю много одинаковых методов.

# ./app/decorators/post_decorator.rb
class PostDecorator < ApplicationDecorator
  delegate_all

  def reactions_total_count
    object.reactions.count
  end

  def reactions_type(kind)
    object.reactions.collect(&:reaction_type).inject(0) {|counter, item| counter += item == kind ?  1 : 0}
  end

  def likes_count
    reactions_type('like')
  end

  def hearts_count
    reactions_type('heart')
  end

  def wows_count
    reactions_type('wow')
  end

  def laughs_count
    reactions_type('laugh')
  end

  def sads_count
    reactions_type('sad')
  end
end


# ./app/decorators/comment.rb
class CommentDecorator < ApplicationDecorator
  delegate_all

  def reactions_total_count
    object.reactions.count
  end

  def reactions_type(kind)
    object.reactions.collect(&:reaction_type).inject(0) {|counter, item| counter += item == kind ?  1 : 0}
  end

  def likes_count
    reactions_type('like')
  end

  def hearts_count
    reactions_type('heart')
  end

  def wows_count
    reactions_type('wow')
  end

  def laughs_count
    reactions_type('laugh')
  end

  def sads_count
    reactions_type('sad')
  end
end

Я хочу, чтобыВыглядит примерно так, но не знаю, куда поместить файлы и какую именно технику мне следует использовать (include против extend).

# ./app/decorators/base.rb
module Base
  # methods defined here
end

# ./app/decorators/post.rb
class PostDecorator < ApplicationDecorator
  delegate_all
  include Base
end

# ./app/decorators/comment.rb
class CommentDecorator < ApplicationDecorator
  delegate_all
  include Base
end

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

Ответы [ 2 ]

0 голосов
/ 29 мая 2018

Я разобрался с ответом Майчера.

Если CommentDecorator находится внутри ./app/decorators/comment_decorator.rb, и мы хотим включить модуль ReactionablesCountable, то нам нужно создать файл внутри./app/decorators/roles/reactions_countable.rb с вложенностью модуля, которая отражает путь к файлу.Например, первая константа в include, (Roles) указывает на папку, которую будет искать Rails, вторая (ReactionsCountable) - это имя файла.

Модульдолжен быть также вложен в этот файл.Я показал это ниже.

module Roles
  module ReactionsCountable
    # methods defined here.
  end
end
0 голосов
/ 29 мая 2018

Прежде всего, я бы выбрал лучшее название для включенного модуля.Это можно рассматривать как роль , используя которую вы будете обогащать классы.Эта роль объявила бы набор *_count методов, которые учитывают что-то в reactions.Поэтому я бы назвал его ReactionsCountable и дополнительно поместил бы его в пространство имен, чтобы отличить его от декораторов: Roles::ReactionsCountable.

Тогда я бы поместил его в:

/app/decorators
  /roles
    /reactions_countable.rb
  /comment.rb
  /post.rb

Другое решение будетиспользовать классическое наследство.Здесь имя Base имело бы смысл ИМО:

class BaseDecorator < ApplicationDecorator
  # declare `*_count` methods here

class PostDecorator < BaseDecorator
class CommentDecorator < BaseDecorator
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...