本文介绍了Ruby on Rails 命名模型的类属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个类 Productuser,它们与多态类型具有 has_many 关系.

I have two classes Product and user which have a has_many relationship with a polymorphic type as such.

class User < ActiveRecord::Base
  has_many :pictures, as: :imageable
end

class Product < ActiveRecord::Base
  has_many :pictures, as: :imageable
end

class Picture < ActiveRecord::Base
   belongs_to :imageable, polymorphic: true
end

我还想为 profile_picture 的用户模型添加一个新属性,以便 @user.profile_picture 将返回一个图片对象.如何做到这一点?特别是向用户添加外键的迁移.

I want to also add a new property to the user models of profile_picture so @user.profile_picture will return a picture object. how can this be achieved? In particular the migration to add the foreign key to users.

我已经更新了用户模型

has_one :profile_picture, class_name: "Picture", foreign_key: "profile_picture_id"

并添加了以下迁移

add_column :users, :profile_picture_id, :integer

但是,如果有人可以解释我到底做错了什么,我似乎无法设置个人资料图片,我们将不胜感激.谢谢!

however i dont appear to be able to set the profile picture if someone could explain what exactly i am doing wrong it would be appreciated. thanks!

推荐答案

当正确使用关联时,没有直接方法可以实现这一点.

There is no direct way to achieve this when using associations properly.

数据结构错误.您正在尝试以两种不同的方式将同一个模型关联起来.问题是:这两种方式相互干扰.

The data structure is wrong. You are trying to associate one and the same model in two different ways. And the problem is: these two ways interfere with each other.

您正在有效地尝试使用相同类型存储不同类型的对象.直接的方法(在另一个答案中建议)会让您无法确定哪些只是 User 的图片,以及其中哪些是他的 profile_picture.因此,任何可能的解决方案都需要添加一种方法来区分 profile_picture.

You are effectively trying to store different types of objects using the same type. A direct way (suggested in another answer) would leave you with no way to determine which are simply User's pictures and what is his profile_picture among them. So any possible solution would require adding a way to distinguish a profile_picture.

就在昨天,我写了一个关于如何使用单表继承".它实际上很适合这里,您需要两个相似的数据结构以不同的方式运行.要使其发挥作用,您需要做两件事:

Just yesterday I wrote an example on how to use "single table inheritance". It actually fits well here, you need two similar data constructs to behave in different ways. To make it work, you will need two things:

  1. pictures 表添加 STI 支持:
    rails g 迁移 AddTypeToPictures type:string:index
    ...并确保您添加了一个 string 类型的 type 列,上面有一个索引.

  1. Add STI support to pictures table:
    rails g migration AddTypeToPictures type:string:index
    ...and make sure you add a type column of type string with an index on it.

rails g 模型 ProfilePicture --no-migration --parent=Picture
该类将创建为空,但会继承 Picture 的所有内容,因此在许多情况下它应该保持为空.

rails g model ProfilePicture --no-migration --parent=Picture
This class will be created empty, but will inherit everything from Picture, so it should stay empty in many cases.

那么一个简单的关联应该适用于任何类:

Then just a simple association should work on any class:

has_one :profile_picture, as: :imageable

假设我们将其添加到 User.那么查找用户头像的搜索条件是:

Let's assume we added this to User. Then the search criteria to find a User's profile picture will be:

  • type"ProfilePicture"
  • imageable_type用户"
  • imageable_id 等于相关用户的 id
  • type is "ProfilePicture"
  • imageable_type is "User"
  • imageable_id is equal to id of the user in question

搜索变得很麻烦,对吧?嗯,这应该可行,但我不推荐所有这些,它有影响和替代方案:

Searches have become cumbersome, right? Well, this should work, but I don't recommend all this, it has implications and alternatives:

  • 无论您决定将哪个数据库列添加到 ProfilePicture,即使没有使用,也必须将其添加到 Picture:它们存储在相同的表.
    解决方案:使 ProfilePicture 成为一个成熟的模型:为它创建一个表,使其继承 ActiveRecord::Base.
  • 获取用户的个人资料图片需要使用三个(哇!)不同条件的额外数据库查询.
    解决方案(推荐):将个人资料图片放入相应的模型中,就像对 Picture 所做的一样:这根本不需要额外的查询来获取个人资料图片.
  • Whatever database column you decide to add to ProfilePicture, it will have to be added to Picture even if it's not used: they are stored in the same table.
    Solution: making ProfilePicture a full-fledged model: make a table for it, make it inherit ActiveRecord::Base.
  • Fetching a user's profile picture will require an extra database query with three (wow!) different criteria.
    Solution (recommended): placing a profile picture inside a corresponding model the same way it's done for Picture: this will require no extra queries to fetch a profile picture at all.

这篇关于Ruby on Rails 命名模型的类属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-11 05:26
查看更多