【问题标题】:Rails Active Record Associations for model which may map to different model types模型的 Rails Active Record 关联可能映射到不同的模型类型
【发布时间】:2014-10-25 00:59:40
【问题描述】:

我正在构建一个具有 UserProduct 类的 RoR 应用程序。一个用户拥有许多照片,就像一个产品一样,但每个用户还必须有一个profile_picture

用户:

class User < ActiveRecord::Base
  has_many :pictures
end

产品:

class Product < ActiveRecord::Base
  has_many :pictures
end

我正在努力定义 pictures 模型,目前是:

class Picture < ActiveRecord::Base
  has_one :user
  has_one :product
end

图片的架构如下(为简洁起见省略了时间戳):

create_table "pictures", force: true do |t|
  t.string   "image_url"
end

最后我进行了迁移,将个人资料图片的链接添加到用户和产品

class AddPicturesToUsersAndWalks < ActiveRecord::Migration
  def change
    add_column :users, :profile_picture, :picture
    add_column :products, :profile_picture, :picture
  end
end

我已经阅读了http://guides.rubyonrails.org/association_basics.htmlhttp://guides.rubyonrails.org/migrations.html 我不明白这些关系应该如何形成,或者外键应该存储在数据库的什么位置。

我无法查看用户或产品表的架构(rake db:migrate 在运行时不会抱怨),因为架构文件中返回了以下错误(我认为这与 profile_picture 相关,但我不确定如何进行:

# Could not dump table "users" because of following NoMethodError
#   undefined method `[]' for nil:NilClass

请注意我在 rails 4 和 sqlite3 数据库上使用 ruby​​

【问题讨论】:

    标签: ruby-on-rails ruby sqlite ruby-on-rails-4 rails-activerecord


    【解决方案1】:

    Rails 文档实际上几乎准确地描述了您应该做什么。

    A polymorphic association.

    class Picture < ActiveRecord::Base
      belongs_to :imageable, polymorphic: true
      # `imageable` is just a name for you to reference and can by anything
      # It is not a class, a table or anything else
      # It affects only corresponding DB column names
    end
    
    class User < ActiveRecord::Base
      has_many :pictures, as: :imageable
      # read as: I am an `imageable`, I can have a picture as one
    end
    
    class Product < ActiveRecord::Base
      has_many :pictures, as: :imageable
    end
    

    在数据库中,这不仅通过id 关联,还通过模型名称来实现:在相应的列&lt;model&gt;_id&lt;model&gt;_type 中。与类名已知且只需要 id 的简单关联相反。

    class CreatePictures < ActiveRecord::Migration
      def change
        create_table :pictures do |t|
          t.string  :data
          t.integer :imageable_id
          t.string  :imageable_type
          t.timestamps
        end
      end
    end
    

    【讨论】:

    • 谢谢,有没有办法链接个人资料图片,以便我也可以使用@user.profile_picture 访问它?
    • @user3576112 看起来像has_one :profile_picture, class_name: "Picture", as: :imageable。类似的东西。
    • 谢谢,那会保存为用户表中的引用还是只是一个图片ID?
    • @user3576112 无视,我错了。所有权存储在belongs_to 一侧,因此无法区分简单图片和个人资料图片。我在想……
    • @user3576112 最好的选择是将图片直接放在 User 模型中作为字段。您不希望每次需要用户时都进行额外查询。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多