问题
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