|
1 | 1 | # PolymorphicIntegerType |
2 | 2 |
|
3 | 3 | Rails' polymorphic associations are pretty useful. The example they give to set it up looks like: |
| 4 | + |
4 | 5 | ```ruby |
5 | 6 | class Picture < ActiveRecord::Base |
6 | 7 | belongs_to :imageable, polymorphic: true |
|
16 | 17 | ``` |
17 | 18 |
|
18 | 19 | With a migration that looks like: |
| 20 | + |
19 | 21 | ```ruby |
20 | 22 | class CreatePictures < ActiveRecord::Migration |
21 | 23 | def change |
@@ -49,38 +51,48 @@ For Rails 3.2 use version < 2. Version >= 2 has been tested on Rails 4.2 and Rub |
49 | 51 |
|
50 | 52 | ## Usage |
51 | 53 |
|
52 | | -The gem is pretty straightforward to use. |
| 54 | +For the model where the `belongs_to` is defined, include `PolymorphicIntegerType::Extensions` and set the `polymorphic:` option to a hash that maps an integer stored in the database to the name of a Ruby class. |
53 | 55 |
|
54 | | -First, include the extensions module and add the `integer_type` option to the associations that are going to be using this. (That way it will play nicely with polymorphic associations whose type you would rather leave as a string.) |
55 | 56 | ```ruby |
56 | 57 | class Picture < ActiveRecord::Base |
57 | 58 | include PolymorphicIntegerType::Extensions |
58 | | - belongs_to :imageable, polymorphic: true, integer_type: true |
| 59 | + |
| 60 | + belongs_to :imageable, polymorphic: {1 => "Employee", 2 => "Product"} |
59 | 61 | end |
| 62 | +``` |
60 | 63 |
|
| 64 | + Next, include `PolymorphicIntegerType::Extensions` into any of the models that point back to the polymorphic integer type association (e.g., `Picture#imageable`) and add a [polymorphic association using `as:`](http://guides.rubyonrails.org/association_basics.html#polymorphic-associations). |
| 65 | + |
| 66 | +```ruby |
61 | 67 | class Employee < ActiveRecord::Base |
62 | 68 | include PolymorphicIntegerType::Extensions |
63 | | - has_many :pictures, as: :imageable, integer_type: true |
| 69 | + |
| 70 | + has_many :pictures, as: :imageable |
64 | 71 | end |
65 | 72 |
|
66 | 73 | class Product < ActiveRecord::Base |
67 | 74 | include PolymorphicIntegerType::Extensions |
68 | | - has_many :pictures, as: :imageable, integer_type: true |
| 75 | + |
| 76 | + has_many :pictures, as: :imageable |
69 | 77 | end |
70 | 78 | ``` |
71 | 79 |
|
72 | | -Second, you need to create a mapping for the polymorphic associations. This should be loaded before the models. Putting it in an initializer is good (`config/initializers/polymorphic_type_mapping.rb`) |
73 | | -```ruby |
74 | | -PolymorphicIntegerType::Mapping.configuration do |config| |
| 80 | +### External mappings |
75 | 81 |
|
76 | | - config.add :imageable, {1 => "Employee", 2 => "Product" } |
| 82 | +You can also store polymorphic type mappings separate from your models. This should be loaded before the models. Putting it in an initializer is one way to do this (e.g., `config/initializers/polymorphic_type_mapping.rb`) |
77 | 83 |
|
| 84 | +```ruby |
| 85 | +PolymorphicIntegerType::Mapping.configuration do |config| |
| 86 | + config.add :imageable, {1 => "Employee", 2 => "Product" } |
78 | 87 | end |
79 | 88 | ``` |
80 | 89 |
|
81 | 90 | Note: The mapping here can start from whatever integer you wish, but I would advise not using 0. The reason being that if you had a new class, for instance `Avatar`, and also wanted to use this polymorphic association but forgot to include it in the mapping, it would effectively get `to_i` called on it and stored in the database. `"Avatar".to_i == 0`, so if your mapping included 0, this would create a weird bug. |
82 | 91 |
|
| 92 | +### Migrating an existing association |
| 93 | + |
83 | 94 | If you want to convert a polymorphic association that is already a string, you'll need to set up a migration. (Assuming SQL for the time being, but this should be pretty straightforward.) |
| 95 | + |
84 | 96 | ```ruby |
85 | 97 | class PictureToPolymorphicIntegerType < ActiveRecord::Migration |
86 | 98 |
|
|
125 | 137 | ``` |
126 | 138 |
|
127 | 139 | Lastly, you will need to be careful of any place where you are doing raw SQL queries with the string (`imageable_type = 'Employee'`). They should use the integer instead. |
128 | | - |
129 | 140 |
|
| 141 | +## Setup |
| 142 | + |
| 143 | +You'll need to have git, Ruby, and MySQL. Then get up and running with a few commands: |
| 144 | + |
| 145 | +```bash |
| 146 | +$ git clone ... |
| 147 | +$ bundle install |
| 148 | +$ vim spec/support/database.yml # Update username and password |
| 149 | +$ bin/setup |
| 150 | +$ bundle exec rspec |
| 151 | +``` |
130 | 152 |
|
131 | 153 | ## Contributing |
132 | 154 |
|
|
0 commit comments