Question

This is most likely a noob question since people use this gem and a lot of people love it, but I don't get the purpose. I'm looking at a project and its been used here many times in places such as t.references :foreign_key_table_name , :foreign_key => true, add_foreign_key :table :foreign_key_table_name, :options, and in a create t.foreign_key :foreign_key_table_name. Hope those weren't confusing since they're out of context.

But I don't get how this is different from what rails does built in with t.references :foreign_key_table_name or from me just adding t.integer :foreign_key_table_name_id? does it simply make it more readable by making clear that this is a 'foreign key'? I could just add a comment instead of a gem if thats the case... The only advantage I see is that you can move options such as :dependent into the migration instead of having it in the model, but who cares?

Was it helpful?

Solution

Some database engines support legit foreign key constraints: if someone tries to save a Child with a parent_id of 5, but there's no Parent with id 5, then the database itself (not Rails) will reject the record if there's a foreign key constraint linking children.parent_id and parents.id.

A foreign key can also specify what happens if the parent is deleted: in MySQL, for example, we can delete or nullify the dependent records, like how Rails does with :dependent, or even just straight-up reject the deletion and throw an error instead.

Since not all database engines offer this functionality, Rails offers to emulate it with :dependent, and it's nice to have it on the software level so that dependent child records can fire their destroy callbacks when the parent is deleted. Since the feature is engine-independent and therefore pretty much schema-independent, Rails doesn't handle the creation/deletion of foreign keys. That's where foreigner comes in: if your engine supports foreign key constraints, and you want that extra confident in your data integrity, foreigner can help with that.

OTHER TIPS

Resurrecting an old question here, but…

Having rails enforce the relationship is fine, within rails itself.

However, if your project grows to have code that also accesses these tables from other languages, that will not have the benefit of rails enforcing the relations. These foreign key constraints are baked into the SQL tables themselves, so can protect non-rails code.

This will also protect you if you need to perform datafixes or otherwise manipulate your data via native SQL.

Another reason is that some documentation tools for SQL look at foreign keys on the DB, so it is cool to have a gem that generates them. Rails 4 added the ability to define foreign keys in the same migration that creates the table with:

t.references :something, foreign_key: true

And the generators will do this for you if you use the references type. Rails adds an index on something_id by default when using foreign_key like this

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top