如何为 has_many 格式化 table 中的字段:通过关联?

How to format fields in a table for has_many :through association?

我有两个模型 - UserImage。我还有第三个模型 - UsersAndImage.

有用户。有图像。我希望用户能够为自己添加图像。为此,documentation.

中清楚地描述了所有内容

我做到了。有了这个,就万事大吉了。

但问题是我需要将状态添加到 users_and_images table:

class UsersAndImage < ApplicationRecord
  enum status: {
    pending: 0,
    active: 1,
    # ...
  }

  belongs_to :user
  belongs_to :image

  validates :user, presence: true
  validates :image, presence: true

  # ...
end

之后我不明白如何进一步描述 User 模型中的连接。也就是我需要使用status.

与table的关系描述如下:

class User < ApplicationRecord
    # ...
    has_many :users_and_images
    has_many :images, through: :users_and_images
    # ...
end

我需要重写此关系,以便根据 link table 的状态进行过滤。也就是说,例如,这段代码:

user = User.find(1)
user.images

仅显示状态为 "active" 的图像。

请告诉我,我该如何实现它?

现在我只看到一种方法 - 这是直接使用 UsersAndImage 模型(类似这样):

user = User.find(1)
user.users_and_images.some_scope_with_where.map(&:image)

但在我看来,这是错误的方法。

也许我需要做这样的事情?

class User < ApplicationRecord
    # ...
    has_many :users_and_images, -> { where(status: UsersAndImage.statuses[:active]) }
    has_many :images, through: :users_and_images
    # ...
end

而在这种情况下,状态的改变应该直接在users_and_images table。但是得到 "filtered" images 会像往常一样。然后如何使用枚举助手?毕竟,我想将它们用于 images,而不是 users_and_images。如果我想获取所有图像怎么办?

你怎么看?

您可以将一个块添加到 has_many 个块。 this question中有一个很好的答案。我以枯燥的方式帮助在 UsersAndImage 中添加这些状态方法。

class User < ApplicationRecord
  has_many : users_and_images
  has_many :images, through: : users_and_images do 
    UsersAndImage.statuses.each do |method_name, value|
      define_method(method_name) do 
        where("users_and_images.status = ?", value)
      end
    end
  end
end

您可以通过 user.images 获取所有图像,通过 user.images.active 获取活动图像,通过 user.images.pending 获取待定图像,通过 user.images.[other status]

获取其他状态