I think changing the semantics of `add_foreign_key` is best saved for
another discussion. The naming change seems to be contentious enough by
itself. ;)

A quick summary of the tradeoffs for human readable names:

+ Consistency with index naming
+ When they show up in query plans, they'll be understandable
- They can fall out of date
- They can be too long and require manual naming

To my mind, the code for renaming them shouldn't be a huge leap from the
same code that's there for indexes. The most obvious issue is support for
constraint renaming in different databases. Postgres only has this in 9.2+,
so we'd have to do version checks. By contrast index renaming support goes
back to at least 8.0. I have no idea about MySQL.

That said, the foreigner gem (which this built-in functionality replaces)
has been generating human readable FK names without renaming them for ages.
I'd be really interested in knowing whether this was a major issue for
people using it (other than me). From what I can see, this got brought up
once (https://github.com/matthuhiggins/foreigner/issues/141) and wasn't
discussed.

I'm getting the feeling this is an issue which just needs someone who's in
charge of activerecord to make a call. I'd like to have the readable names
back myself, but it's not my call and opinions are pretty divided on here.

On 17 January 2015 at 12:08, Will Bryant <will.bry...@gmail.com> wrote:

> True - good point.  Using random values is a bit weird though, since two
> people running the same migration will get different names, and then their
> schemas will never quite match.  This means dev machines’ schemas will
> differ from staging/test environments and them from production.
>
> Wouldn’t a simple CRC hash of the input data equally solve the issue of
> names potentially getting out of date, without introducing non-determinancy?
>
> More way-too-late bikeshedding: IMHO the method in 4.2 should be renamed
> to add_foreign_key_with_constraint.  A foreign key is just the key for an
> association.  A foreign key constraint is a different concept to a foreign
> key.
>
> IMHO it’s really important that users understand the difference, and only
> add constraints when they want them.
>
> The thing is, if you live your life on recent versions of PostgreSQL, they
> work well enough to be usable.  But on MySQL particularly - and in
> PostgreSQL before they implemented the special weakened lock types - they
> cause a lot of unintended side effects because they result in a standard
> shared lock being taken on the parent row.
>
> On one of my big apps we put FKCs in in ~2008, and we’re now actually
> going through dropping FKCs when we get the chance, because they just cause
> too many problems at runtime.
>
> Basically, if table A is a parent to table B, and you have an FKC linking
> the two, then an update to a B row will take some kind of shared lock on
> A.  But it’s also common to have a form for A records which nests B
> records, and then in practice the #update action is going to save A, and
> then save the Bs… and then you get deadlocks.
>
> I’ve been finding this sort of problem (there’s others) comes up so often
> that I’ve gone right off the idea of foreign key constraints, and now tell
> ppl to only add them when they specifically need them.  (And I find usually
> it’s relatively rare that you do in practice because a lot of parent tables
> don’t get deletes, and those that do you tend to want to seralize things
> using update locks anyway.)
>
> TL;DR I would like people to learn from our mistakes and not to
> accidentally get foreign key constraints when they think they are just
> adding a foreign key :).
>
>
> On 17/01/2015, at 23:32 , Yves Senn <yves.s...@gmail.com> wrote:
>
> Yes, they are shown in constraint error messages, but so are the metadata
> (table name and referenced column name).
> Following are example messages:
>
> MySQL:
> -----------
> ERROR 1452 (23000): Cannot add or update a child row: a foreign key
> constraint fails (`activerecord_unittest`.`fk_test_has_fk`,
> CONSTRAINT `fk_rails_bde121d5a6` FOREIGN KEY (`fk_id`) REFERENCES
> `fk_test_has_pk` (`id`))
>
> PostgreSQL:
> -----------------
> ERROR:  insert or update on table "fk_test_has_fk" violates foreign key
> constraint "fk_rails_bde121d5a6"
> DETAIL:  Key (fk_id)=(98493849) is not present in table "fk_test_has_pk".
>
> Both messages have all the detail needed to understand what's going on.
> From that perspective
> I don't see the need to duplicate the metadata in the constraint name.
>
> Simon: I didn't know about that. Is there a discussion or documentation
> that goes into
> further detail? I'd like to read up on these planed changes. This could
> affect what
> implementation we are going to pursue.
>
> Cheers,
> -- Yves
>
> On Saturday, January 17, 2015 at 2:01:25 AM UTC+1, will.bryant wrote:
>>
>> They may not be shown in query plans, but they are shown in constraint
>> error messages, and the possibility of hitting those errors is the whole
>> reason one adds foreign key constraints.  It’s helpful to have an
>> indication which kind of constraint was invalidated without having to look
>> through the schema.
>>
>> We do already tolerate the index names being irrelevant if they become
>> inconsistent, but in my personal experience that doesn’t happen very often
>> at all, since I’ve found indexed columns tend to be important and keep
>> their names.
>>
>> So I would vote for meaningful names too.  Just my 2c.
>>
>>
>> On 16/01/2015, at 01:42 , Yves Senn <yves...@gmail.com> wrote:
>>
>> Hey Chris
>>
>> Sorry for my late response.
>>
>> tl;dr: I'd rather not go for consistency with index naming but for a
>> consistent hash approach.
>>
>> We have descriptive names for indexes because they are shown to the user
>> in query plans.
>> This is not the case with foreign keys. When inspecting a database you
>> can look at the
>> constraint metadata. I don't see much value in encoding that metadata
>> into the name.
>>
>> In my opinion the drawbacks in the implementation are more sever. We
>> faced a lot of issues
>> when automatically renaming indexes. There are still cases where they
>> fall out of sync
>> with the actual metadata. Having descriptive names, which no longer
>> represent the metadata
>> is way worse in my opinion.
>> Also constant renaming when renaming tables and columns is not very
>> practical. The added
>> issue of the limited size makes this even worse.
>>
>> My gut feeling is in favor of constant non-descriptive names. I do
>> remember that I implemented
>> that exact behavior but we pivoted to purely random names. I'd like to go
>> through our archived
>> discussions regarding that change to make sure we have all the needed
>> information.
>> I haven't had the time to do so.
>>
>> Cheers,
>> -- Yves
>>
>> On Thursday, January 15, 2015 at 1:25:18 PM UTC+1, ch...@sinjakli.co.uk
>> wrote:
>>>
>>> My own preference is towards the longer, descriptive names. Partly for
>>> consistency with index naming, and partly because it's nice to be able to
>>> glance at them and know what they are (though I understand the argument for
>>> them falling out of date).
>>>
>>> I'll go ahead and make a PR for that option. If there's serious
>>> objections to it, hashing is easy enough to add. Thanks for sharing your
>>> thoughts on this!
>>>
>>> Cheers,
>>> Chris
>>>
>>> On Tuesday, January 13, 2015 at 9:19:37 PM UTC, James Coleman wrote:
>>>>
>>>> As far as the Postgres limit, that also applies to index names. So I
>>>> don't see why we need to handle it any different for foreign keys (i.e.,
>>>> with indexes it just means that it fails on creation if the auto-generated
>>>> one is too long and the dev has to provide a manual name.)
>>>>
>>>> On Tue, Jan 13, 2015 at 4:15 PM, Amiel Martin <am...@carnesmedia.com>
>>>> wrote:
>>>>
>>>>> My vote would be to be consistent with the way index names work; the
>>>>> long human readable version.
>>>>>
>>>>> -Amiel
>>>>>
>>>>> On Tue, Jan 13, 2015 at 12:31 PM, Ken Collins <k...@actionmoniker.com>
>>>>>  wrote:
>>>>>
>>>>>> Though I have not felt the pain, I have been a long time user of
>>>>>> structure files in legacy environments and think consistent names are a
>>>>>> good idea. On the flip side, the same could be said for constraint name
>>>>>> “churn” too. I have seen this in big Oracle teams and unavoidable to my
>>>>>> knowledge and/or only fixed with a custom script after the rake migration
>>>>>> task.
>>>>>>
>>>>>> All that said, I think this is something Rails could solve and the PG
>>>>>> limit does seem like a big constraint too.
>>>>>>
>>>>>>  - Cheers,
>>>>>>    Ken
>>>>>>
>>>>>> On January 13, 2015 at 11:12:47 AM, ch...@sinjakli.co.uk (
>>>>>> ch...@sinjakli.co.uk) wrote:
>>>>>>
>>>>>> I'm really glad to see foreign key support has made its way into
>>>>>> Rails migrations, but very quickly ran into an issue with it when working
>>>>>> in teams using structure.sql.
>>>>>>
>>>>>> Previously, we'd been using the foreigner gem, which generated FK
>>>>>> names based on the table and column. This meant the name was consistent
>>>>>> every time you ran the migration. With the version that made it into 
>>>>>> 4.2, part
>>>>>> of the FK name is random
>>>>>> <https://github.com/senny/rails/commit/8768305f20d12c40241396092a63e0d56269fefe#diff-a0775e1ec64264dc76a8ee71a5211ae3R697>.
>>>>>> This means every dev who runs the migration locally generates a different
>>>>>> version of structure.sql, leading to conflicts in version control.
>>>>>>
>>>>>> Right now we're working round this by explicitly setting the FK name
>>>>>> in our migrations. I'd like to find a way of fixing this in Rails itself
>>>>>> though.
>>>>>>
>>>>>> My understanding was the reason for switching away from the old
>>>>>> format was that the name is arbitrary, and can fall out of date on column
>>>>>> renames. By itself I'm not totally convinced that's enough reason to get
>>>>>> rid of the more descriptive names (though I agree it's debatable). The
>>>>>> restriction on the length of the name (63 characters in Postgres, for
>>>>>> example) is a more compelling reason for me.
>>>>>>
>>>>>> Either way, I'd like to contribute a patch to make migrations
>>>>>> generate consistent FK names. I'm happy to implement either of the
>>>>>> following (or something else if anyone's got a better ideas):
>>>>>>
>>>>>> * Switch back to generating human-readable names, accept that people
>>>>>> with long table/column names will occasionally have to set them manually
>>>>>> * Generate that human-readable name, hash it, and append a substring
>>>>>> of the hash to "fk_rails_". This would give you a name which is both 
>>>>>> short
>>>>>> and consistent.
>>>>>>
>>>>>> Would really appreciate feedback on those approaches.
>>>>>>
>>>>>> Cheers,
>>>>>> Chris
>>>>>> --
>>>>>> You received this message because you are subscribed to the Google
>>>>>> Groups "Ruby on Rails: Core" group.
>>>>>> To unsubscribe from this group and stop receiving emails from it,
>>>>>> send an email to rubyonrails-co...@googlegroups.com.
>>>>>> To post to this group, send email to rubyonra...@googlegroups.com.
>>>>>> Visit this group at http://groups.google.com/group/rubyonrails-core.
>>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>>
>>>>>>
>>>>>> --
>>>>>> You received this message because you are subscribed to the Google
>>>>>> Groups "Ruby on Rails: Core" group.
>>>>>> To unsubscribe from this group and stop receiving emails from it,
>>>>>> send an email to rubyonrails-co...@googlegroups.com.
>>>>>> To post to this group, send email to rubyonra...@googlegroups.com.
>>>>>> Visit this group at http://groups.google.com/group/rubyonrails-core.
>>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> You received this message because you are subscribed to the Google
>>>>> Groups "Ruby on Rails: Core" group.
>>>>> To unsubscribe from this group and stop receiving emails from it, send
>>>>> an email to rubyonrails-co...@googlegroups.com.
>>>>> To post to this group, send email to rubyonra...@googlegroups.com.
>>>>> Visit this group at http://groups.google.com/group/rubyonrails-core.
>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>
>>>>
>>>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "Ruby on Rails: Core" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to rubyonrails-co...@googlegroups.com.
>> To post to this group, send email to rubyonra...@googlegroups.com.
>> Visit this group at http://groups.google.com/group/rubyonrails-core.
>> For more options, visit https://groups.google.com/d/optout.
>>
>>
>>
> --
> You received this message because you are subscribed to the Google Groups
> "Ruby on Rails: Core" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to rubyonrails-core+unsubscr...@googlegroups.com.
> To post to this group, send email to rubyonrails-core@googlegroups.com.
> Visit this group at http://groups.google.com/group/rubyonrails-core.
> For more options, visit https://groups.google.com/d/optout.
>
>
>  --
> You received this message because you are subscribed to the Google Groups
> "Ruby on Rails: Core" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to rubyonrails-core+unsubscr...@googlegroups.com.
> To post to this group, send email to rubyonrails-core@googlegroups.com.
> Visit this group at http://groups.google.com/group/rubyonrails-core.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Core" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to rubyonrails-core+unsubscr...@googlegroups.com.
To post to this group, send email to rubyonrails-core@googlegroups.com.
Visit this group at http://groups.google.com/group/rubyonrails-core.
For more options, visit https://groups.google.com/d/optout.

Reply via email to