3

I have three objects:

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

class Employee < ActiveRecord::Base
  has_many :pictures, :as => :imageable  
end

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

How should I create test seed data, to associate an image with both a seed employee and seed product ?

P3rishable
  • 83
  • 10

2 Answers2

2

Create them from the has_many end instead:

employee = Employee.create! fields: 'values'
employee.pictures.create! fields: 'values'

product = Product.create! fields: 'values'
product.pictures.create! fields: 'values'

Although just one quick note: when seeding, you may already have the data you want in the database, so I would use instance = Model.where(find_by: 'values').first_or_create(create_with: 'values') instead.

NB. I've just noticed: you're not trying to associate one image with multiple owners, are you? Because each image only belongs to one Imageable, and that is either an Employee or a Product. If you want to do that, you'll have to set up a many-to-many join.

PJSCopeland
  • 2,818
  • 1
  • 26
  • 40
  • 1
    Right. Do `Employee`s and `Product`s *need* many pictures? (If so then ignore this comment, but) if not, you could just reverse the join - put the foreign keys to `picture` on those tables - and then you can just have two `has_many`s on the `Picture` side, with no need for them to be polymorphic. – PJSCopeland Feb 12 '16 at 00:29
2

to associate an image with both a seed employee and seed product

This would require a many-to-many relationship (either has_and_belongs_to_many or has_many :through):

#app/models/product.rb
class Product < ActiveRecord::Base
  has_many :images, as: :imageable
  has_many :pictures, through: :images
end

#app/models/employee.rb
class Employee < ActiveRecord::Base
  has_many :images, as: :imageable
  has_many :pictures, through: :images
end

#app/models/image.rb
class Image < ActiveRecord::Base
  belongs_to :imageable, polymorphic: true
  belongs_to :picture
end

#app/models/picture.rb
class Picture < ActiveRecord::Base
  has_many :images
end

This would allow you to use:

#db/seed.rb
@employee = Employee.find_or_create_by x: "y"
@picture  = @employee.pictures.find_or_create_by file: x

@product = Product.find_or_create_by x: "y"
@product.pictures << @picture

ActiveRecord, has_many :through, and Polymorphic Associations


Because you're using a polymorphic relationship, you won't be able to use has_and_belongs_to_many.

The above will set the polymorphism on the join table; each Picture being "naked" (without a "creator"). Some hacking would be required to define the original creator of the image.

Community
  • 1
  • 1
Richard Peck
  • 76,116
  • 9
  • 93
  • 147