0

I'm new to rails and I'm facing a problem with how to set up my models.

  1. I've got a set of models: Balloon, Paint, Brush etc.
  2. They have common attributes (like "name")
  3. I want them to have a unique id. That is I want that if there is an instance of Balloon with an id=NNN, then Paint.find(NNN) and Brush.find(NNN) return nil.

An obvious solution would be to create a model, say Item, which Balloon, Paint and Brush are inherited from. But this approach sort of smells, because subclasses Balloon, Paint and Brush are indeed quite different. The only thing I need from them is that id attribute be unique among these subclasses.

I've heard about composition and delegation in Rails but I'm not fluent with them, so I don't know what is the reasonable way to resolve the problem.

Andrew
  • 2,148
  • 5
  • 23
  • 34

3 Answers3

1

I think you should go with the solution of creating the Item model. You want the same behavior for Balloon, Paint and Brush, so they should inherit their common behavior. You are right they are different, that is why you will have Balloon, Paint and Brush in the first place instead of using only your Item model. I believe this should be resolved by inheritence.

Lajos Arpad
  • 64,414
  • 37
  • 100
  • 175
0

Why fight with Rails to make the (arbitrary) record id be unique across tables? If you want a unique token across multiple models, create a virtual attribute (say, vid) that adds a 'B' to the record id of a balloon record, 'P' to paint, 'R' to brush, or whatever. Write a find() for each model that takes such a vid and returns nil if the vid is wrong for the model, otherwise issuing a find() with the record id.

Fred
  • 8,582
  • 1
  • 21
  • 27
  • yes, this might be a way out. But is it elegant enough? What if in future another model will appear? – Andrew Apr 08 '13 at 21:19
  • The virtual id is the rails record id (unique within the table) plus some data that is specific to each model/database. The result will be unique across all records in all models/databases. The model knows how to translate virtual ids to and from the model-specific rails record id. Each model has a find() that knows to return a nil if it is given a virtual id which does not have the correct model-specific part. Comparing virtual ids from different models will always evaluate to not-equal, even if the underlying record ids are equal. – Fred Apr 08 '13 at 21:55
0

I solved the problem in this way:

  1. I did introduce model Item.
  2. I updated the models Paints and Brushes by adding :after_save filter which in fact saves to the database Item corresponding information.

I don't know whether it is a "my own bicycle", but it seems to work.

Andrew
  • 2,148
  • 5
  • 23
  • 34