Rails Active Record Associations for model which may map to different model types

妖精的绣舞 提交于 2019-12-23 05:19:38

问题


I'm building an RoR application which has a User and Product classes. A user many have many photos as may a product, but each must also have a single profile_picture.

Users:

class User < ActiveRecord::Base
  has_many :pictures
end

Products:

class Product < ActiveRecord::Base
  has_many :pictures
end

I'm struggling to define the pictures model which is currently:

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

The schema for pictures is as follows (timestamps omitted for brevity):

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

finally I have a migration to add a link for the profile picture to users and products

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

I've read through http://guides.rubyonrails.org/association_basics.html and http://guides.rubyonrails.org/migrations.html I don't understand how these relationships should be formed or where in the database the foreign keys should be stored.

I cannot view the schema for the user or products table (rake db:migrate does not complain when run) because the following error is returned in the schema file (I assume this is related to the profile_picture in both but im unsure how to procede:

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

Please note im using ruby on rails 4 and a sqlite3 database


回答1:


Rails documentation actually describes almost precisely what you should do.

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

In database this is accomplished by associating not only through id, but also through a model name: in corresponging columns <model>_id and <model>_type. As opposed to simpler associations where class name is known and only an id is needed.

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


来源:https://stackoverflow.com/questions/25594975/rails-active-record-associations-for-model-which-may-map-to-different-model-type

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!