-
Notifications
You must be signed in to change notification settings - Fork 86
has_one (unique index) vs has_many (index) #157
Comments
you're last one is right,
is the way to do a has_one. (that's even described in the README for https://github.com/lomba/schema_associations) not sure why you ended up with two indexes, though -- is it possible you had an index already defined by a previous migration? |
I'm starting fresh so nothing previously existed. I gotta think I'm doing something wrong. But here's what I tried: made a new rails project couldn't get away with:
as the unique wasn't there at all had to use:
which is weird
and the result:
and
Thanks so much for looking at this. |
hm, maybe you have discovered a bug. what versions of rails, schema_plus, etc. are you using? |
|
I just double validated with this syntax model:
I get
and with
I get:
|
thanks for the info -- will look into it as soon as i get a chance... |
Very welcome. Please let me know what I can do to help. |
In case it's not obvious, the workaround would to delete the unwanted index in a later line in the migration.
Well, if you're motivated to dive into the code and debug it.... ;) |
I'm happy to do that. Can I ask you to point me to the file where the index should be created? It's ruby so everything is factored so well that i keep going from file to file. I'd also like a sanity check that I'm in the right place before. :) Thanks much. |
I'd start by looking at active_record/column_options_handler.rb, which has the (mildly nasty) logic for processing options and creating an index implicitly or explicitly. BTW I believe that some of the features that used to provided by only schema_plus are now provided by rails 4.* (my own projects are still pinned to rails 3.2 so truth is i haven't had a chance to investigate rails 4.* deeply.). In particular i think rails now supports creating an index as an option to the column definition; so conceivably what's happening is that both rails and schema_plus are processing the Thanks for being willing to look into it! |
Thanks for the pointers on rails 4. That sent me down the right road. Here's what I found: At minimum in rails 4.0.2 we have code for "add_reference" that looks like this: http://apidock.com/rails/v4.0.2/ActiveRecord/ConnectionAdapters/SchemaStatements/add_reference
the add_index creates:
in response to:
which in my opinion makes the schema_plus index redundant:
The question is how do you want to handle such a case. I would vote for not creating the fk__child_parent_id index. I have tested this with the following temp test:
I would think a conditional for the rails version that started adding the index would be the best solution. What do you think? |
when I comment out "add_index" in def column_index this:
also works to create:
|
Yep, seems reasonable. I'd suggest/request going the full TDD route. That is:
and checks that it creates exactly one index, and that the index is unique. Verify that the test fails (when you run Sound good? Thanks! |
I'm not much of a TDD guy as invariably the tests are never right (as we see in this case :( ). Here's the patch:
which if called like this:
yields:
|
No need to go off into a discussion testing philosophies. I'm not a hardcore TDD guy either. But IMHO in this case it's appropriate. But if you're not up for it, that's OK, i'll do it myself when I get a chance. And in any case thanks for reporting the bug and tracking down the problem! |
My apologies. I didn't mean to be confrontational. I honestly wouldn't even know where to start writing the tests. |
I was thinking more about this. For rails >= 4.0 we are basically not making a "schema_plus" index in this case. So what would we be testing? Wouldn't the tests just refer to rails for testing? |
Yeah, I agree for the most part the existing tests should cover it -- take out that line and everything should continue to work as normal. So why write a new test? A couple of reasons that make it seem appropriate for this type of bug fix: First a sanity check, to make sure that the test rig has the same environmental setup as what caused you to see the bug. If the test doesn't fail we'd know the problem is more mysterious than we thought. That's less of an issue since you've already tracked down the problem, but still it can't hurt to doublecheck given how large and sometimes obscure rails with all its components (including schema_plus) can be. Next, a hedge against future changes. E.g. it's possible that there are circumstances in which schema_plus will want to generate an index that rails wouldn't normally generate, or in which schema_plus might need to take over creating the index to give it options that rails doesn't support. We'll find out if that's the case now when we run the full specs, or it might come up in the future (e.g. to fix things for #159 maybe?). So at some point the simple conditional in your patch might need to change to some more complex logic -- and having the new test in place would make sure we didn't accidentally introduce a bug in that logic which would lead to indexes be created by both rails and schema_plus. (And, as you found, the existing tests don't catch that problem!) |
OK. I've taken care of this. Thanks again for reporting and tracking down the problem. BTW score one for TDD: The patch was indeed overbroad; ActiveRecord 4.* doesn't always create indexes where schema_plus does, and where it does create them, it doesn't support all the syntax that schema_plus does. So I indeed needed to put in some different logic and having the new test in place was very handy to make sure I navigated the logic properly to get the new tests to pass while not causing the existing tests to fail. |
Wow - Thanks so much! That's great news! |
Sorry to bother. I realize this all works the way it is. Great GEM! Thank you all!
However, in the purest sense shouldn't the index created on a foreign key (child_id) be unique if has_one and not unique if has_many?
I looked for quite a while for a way to do it. I didn't find a way other than going fully manual on the index. Did I miss something?
something like:
or maybe
I tried
but I ended up with two indexes.
The text was updated successfully, but these errors were encountered: