New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Automatically create indexes for references/belongs_to statements in migrations. #5262
Conversation
I think it's healthy to explicitly add indexes, but I think this should be the default. Nice patch; needs a changelog bump and some guide/docs updates! |
Thanks! I'll get right on that :) |
args.each do |col| | ||
column("#{col}_id", :integer, options) | ||
column("#{col}_type", :string, polymorphic.is_a?(Hash) ? polymorphic : options) unless polymorphic.nil? | ||
index("#{col}_id", index_options.is_a?(Hash) ? index_options : nil) unless index_options == false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should add an index including both #{col}_id
and #{col}_type
? I know It would work fine in MySQL because it can uses just part of the index, unsure how it would play with other databases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought about that - I can try it out this week and see how it works. You're talking about something like this?
index(polymorphic ? %w(id type).map { |t| "#{col}_#{t}" } : "#{col}_id", index_options.is_a?(Hash) ? index_options : nil)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to work. I tested mysql, mysql2, postgres and sqlite as those are what I have. I would imagine that this shouldn't introduce any major problems with the others since it's using existing rails behavior to add the indexes. Can anyone confirm?
Nice patch! There are a couple things we need to have in mind though:
My $0.02: this patch adds a simpler syntax to add indexes which is welcome but I wouldn't make this the default. I would simply improve the current generators. /cc @jeremy @tenderlove |
I'll hold off on updating the docs and changelog until we decide which option to go with. I tend to agree with @josevalim; the generator could be modified to add |
@joshuap I think explicitly updating the generators and emitting a warning if there is no index is the right way to go. We may also want a flag to shut off the warning? I'm not sure. I don't know why anyone would want a |
Unfortunately we cannot add a warning as this would mean we would print a warning for all old migrations. Unless we create a new method. |
@josevalim good point. Nevermind about the warning then. Although.... Migrations should have a timestamp, we could only display the warning if the migration is new enough. ;-) |
Deny. I could upgrade my app one year after Rails 4 was released :P |
@josevalim sure, just make test for one year plus one day. |
I was thinking that to shut off the warning, you could add |
Ya, I guess we should do "update generators, but no warning". |
Great, I'll try to get that knocked out later this week. |
Indexes must now be explicitly defined using the :index option, model/scaffold generators now use the new syntax, and I've updated the guides/doc/changelog. Tests are all passing for MySQL, Sqlite, and Postgres. |
@josevalim @tenderlove ready for merge (or feedback) |
# | ||
# create_table :taggings do |t| | ||
# t.integer :tag_id, :tagger_id, :taggable_id | ||
# t.string :tagger_type | ||
# t.string :taggable_type, :default => 'Photo' | ||
# end | ||
# add_index :taggings, :tag_id, :name => 'index_taggings_by_tag_id' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
index_taggings_on_tag_id
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, my original logic behind that was I wanted to show that it was setting something other than the default, but I wasn't nearly explicit enough. Updated.
Looks good! Could you rebase against master? |
@jeremy done! |
Automatically create indexes for references/belongs_to statements in migrations.
@@ -21,6 +21,10 @@ def parse(column_definition) | |||
has_index, type = type, nil if INDEX_OPTIONS.include?(type) | |||
|
|||
type, attr_options = *parse_type_and_options(type) | |||
|
|||
references_index = (type.in?(%w(references belongs_to)) and UNIQ_INDEX_OPTIONS.include?(has_index) ? {:unique => true} : true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@joshuap We don't use and
. Can you change it please?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed in 3b0ffb1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks - sorry I didn't get to this in time, busy with client work :)
can we use below syntax for indexing? |
My attempt at solving an annoyance mentioned a couple weeks ago by @tenderlove, where using "references" or "belongs_to" when creating/changing a table in a migration does not create a corresponding index, even though in most cases it is needed.
One consideration is that most developers will have already specified indexes for these columns in their existing migrations... I'm not sure if that will be a problem or not moving forward. I'm happy to make additional changes if need be.