继承 Rails 中的模型

发布于 2024-10-05 22:34:56 字数 532 浏览 7 评论 0原文

我有 2 个类似的模型:

liked_image_user
loved_image_user

我已将常用方法放入模块 Rating.rb 中,并将其包含在每个类中 方法是:

update_score
notify

通知正在访问

self.image
self.user

like_image_user/loved_image_user 的成员

我有 2 个问题:

  • 这是正确的设计吗?它似乎 对我来说我正在做一件丑陋的事 副作用,考虑评级为 基类,但实际上是 一个模块
  • 只是我正在编写的 rating_test.rb 现在,并且有 问题测试通知因为 self.image 指的是固定装置和 不是班级的成员,是 有一种方法可以让我忽略固定装置 并覆盖 self.image?

I have 2 similar models:

liked_image_user
loved_image_user

I have put the common methods in a module Rating.rb, that I include in each class
methods are:

update_score
notify

notify is accessing

self.image
self.user

member of liked_image_user/loved_image_user

I have 2 problems:

  • Is that the right design? It seems
    to me that I am doing an ugly
    side-effect, considering Rating as
    the base-class, but it's actually
    only a module
  • I am writing
    rating_test.rb right now, and have
    problem testing notify because
    self.image refers to the fixture and
    not the member of the class, is
    there a way I can ignore the fixture
    and override self.image?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

淡淡の花香 2024-10-12 22:34:56

对模型类使用继承是 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.likeduser.images.loved 获取任何用户喜欢/喜爱的图像。

如果您将两个评级合并到一个字符串列中并为评级类型创建范围,这可能会更清晰;这取决于您的应用程序将如何准确运行。

Using inheritance with model classes is how Rails does STI, so that would likely not do what you expect.

This is probably becoming a mess because you have the relationships set up wrong. I think this is a more appropriate case for a has_many :through relation.

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

With a little validation and a couple simple scopes, you can get the liked/loved images of any user with user.images.liked or user.images.loved.

This might be cleaner if you combined the two ratings into a string column and created scopes for the rating type; that depends on how your application is going to work exactly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文