наследование моделей в рельсах - PullRequest
1 голос
/ 04 декабря 2010

У меня есть 2 аналогичные модели:

liked_image_user
loved_image_user

Я поместил общие методы в модуль Rating.rb, которые я включаю в методы каждого класса:

update_score
notify

notifyполучает доступ к

self.image
self.user

члендобавлено в_пользователь_изображения_изображения_пользователя_изображения_изображения_изображения_пользователя

У меня 2 проблемы:

  • Это правильный дизайн?Мне кажется, что я делаю некрасивый побочный эффект, рассматривая Rating как базовый класс, но на самом деле это всего лишь модуль
  • . Я пишу rating_test.rb прямо сейчас, и у меня есть тестирование проблемы, уведомляющее, потому что self.image относится к устройству, а не к классу, есть ли способ, которым я могу игнорировать прибор и переопределить self.image?

1 Ответ

2 голосов
/ 04 декабря 2010

Использование наследования с классами моделей - это то, как Rails выполняет STI, так что это, скорее всего, не будет соответствовать вашим ожиданиям.

Вероятно, это становится беспорядком, потому что у вас неправильно настроены отношения. Я думаю, что это более подходящий случай для отношения has_many :through.

class User < ActiveRecord::Base
  has_many :ratings
  has_many :images, :through => :ratings do
    def liked
      where(:ratings => { :like => true })
    end

    def loved
      where(:ratings => { :love => true })
    end
  end
end

class Rating < ActiveRecord::Base
  belongs_to :user
  belongs_to :image
  attr_accessible :like, :love
  validates_with RatingValidator
end

class Image < ActiveRecord::Base
  has_many :ratings
  has_many :users, :through => :ratings
end

class RatingValidator < ActiveModel::Validator
  def validate(record)
    record.errors[:base] << "only one rating per image is allowed" unless record[:like] ^ record[:love]
  end
end

С небольшой проверкой и парой простых областей действия вы можете получить понравившиеся / любимые изображения любого пользователя с помощью user.images.liked или user.images.loved.

Это может быть чище, если вы объединили две оценки в столбец строки и создали области для типа оценки; это зависит от того, как ваше приложение будет работать точно.

...