Skip to content

Commit d766d8a

Browse files
author
Kyle d'Oliveira
committed
Readme update
1 parent b079dd2 commit d766d8a

1 file changed

Lines changed: 110 additions & 2 deletions

File tree

README.md

Lines changed: 110 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,35 @@
11
# PolymorphicIntegerType
22

3-
TODO: Write a gem description
3+
Rails' polymorphic assocaitions are pretty useful. The example they give to set it up looks like:
4+
```ruby
5+
class Picture < ActiveRecord::Base
6+
belongs_to :imageable, polymorphic: true
7+
end
8+
9+
class Employee < ActiveRecord::Base
10+
has_many :pictures, as: :imageable
11+
end
12+
13+
class Product < ActiveRecord::Base
14+
has_many :pictures, as: :imageable
15+
end
16+
```
17+
18+
With a migration that looks like:
19+
```ruby
20+
class CreatePictures < ActiveRecord::Migration
21+
def change
22+
create_table :pictures do |t|
23+
t.string :name
24+
t.integer :imageable_id
25+
t.string :imageable_type
26+
t.timestamps
27+
end
28+
end
29+
end
30+
```
31+
32+
The problem with this approach is the `imageable_type` is a string (and by default it is 255 characters). This is a little rediculous. For comparison, if we had a state machine with X states, would be describe the states with strings `"State1", "State2", etc` or would be just enumerate the state column and make it an integer. This gem will make it so we can use an integer for the `imageable_type` column.
433

534
## Installation
635

@@ -18,7 +47,86 @@ Or install it yourself as:
1847

1948
## Usage
2049

21-
TODO: Write usage instructions here
50+
The gem is pretty straightforward to use.
51+
52+
First, include the extensions module and add the `integer_type` option to the assocaitions that are going to be using this. (That way it will play nicely with polymorphic association you would rather the type remain as a string)
53+
```ruby
54+
class Picture < ActiveRecord::Base
55+
include PolymorphicIntegerType::Extensions
56+
belongs_to :imageable, polymorphic: true, :integer_type => true
57+
end
58+
59+
class Employee < ActiveRecord::Base
60+
include PolymorphicIntegerType::Extensions
61+
has_many :pictures, as: :imageable, :integer_type => true
62+
end
63+
64+
class Product < ActiveRecord::Base
65+
include PolymorphicIntegerType::Extensions
66+
has_many :pictures, as: :imageable, :integer_type => true
67+
end
68+
```
69+
70+
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`)
71+
```ruby
72+
PolymorphicIntegerType::Mapping.configuration do |config|
73+
74+
config.add :imageable, {1 => "Employee", 2 => "Product" }
75+
76+
end
77+
```
78+
79+
Note: The mapping here can start from whatever integer you wish, but I would advise not to use 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.
80+
81+
If you want to migrate from a polymorphic association that is already a string you'll need to setup a migration (assuming sql for the time being. But this should be pretty straightforward)
82+
```ruby
83+
class PictureToPolymorphicIntegerType < ActiveRecord::Migration
84+
85+
def up
86+
execute <<-SQL
87+
ALTER TABLE pictures
88+
ADD COLUMN new_imageable_type INTEGER
89+
SQL
90+
91+
execute <<-SQL
92+
UPDATE reminders
93+
SET new_imageable_type = CASE imageable_type
94+
WHEN 'Employee' THEN 1
95+
WHEN 'Product' THEN 2
96+
END
97+
SQL
98+
execute <<-SQL
99+
ALTER TABLE pictures
100+
DROP COLUMN imageable_type,
101+
CHANGE COLUMN new_imageable_type imageable_type INTEGER
102+
SQL
103+
end
104+
105+
def down
106+
execute <<-SQL
107+
ALTER TABLE pictures
108+
ADD COLUMN new_imageable_type VARCHAR(255)
109+
SQL
110+
111+
execute <<-SQL
112+
UPDATE picture
113+
SET new_imageable_type = CASE imageable_type
114+
WHEN 1 THEN 'Employee'
115+
WHEN 2 THEN 'Product'
116+
END
117+
SQL
118+
execute <<-SQL
119+
ALTER TABLE picture
120+
DROP COLUMN imageable_type,
121+
CHANGE COLUMN new_imageable_type imageable_type VARCHAR(255)
122+
SQL
123+
end
124+
end
125+
```
126+
127+
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+
22130

23131
## Contributing
24132

0 commit comments

Comments
 (0)