Some Rails plugins: Real FK

Submitted by gwolf on Tue, 04/08/2008 - 20:42.

I have mostly shifted my main development language to Ruby, as most of the work I do tends to be pretty well covered with Rails. That's not new, however - What is new is that I feel I have got to the point where I actually have something to share. And it feels very good.
So my next couple of posts (three, actually) will be covering some plugins I've written. They are, of course, just sketched - but they work reliably enough to be deemed as useful by their author ;-)
Today I will start by blogging about RealFK. Of course, I will be copying from its documentation/description - I wrote it as well, so I'm not really plagiarizing my own site. I'm not suing self. You can of course also browse the RealFK SVN tree.

References

Rails is built upon a "dumb database" concept. Rails assumes the database will not force restrictions upon the user - i.e. that the model validators are all there is. But I disagree ;-) I was raised with PostgreSQL, not with MySQL, and I do believe the database can and should impose sane values - It should impose trust on the data..
So, if you want to create a relation field, properly acting as a foreign key and refering to another table, instead of doing it via the ActiveRecord::ConnectionAdapters::TableDefinition#column (or even ActiveRecord::ConnectionAdapters::TableDefinition#references) methods, declare them with add_refrence:

  1. def self.up
  2. create_table :proposals do |t|
  3. (...)
  4. end
  5. create_table :proposal_types do |t|
  6. (...)
  7. end
  8. create_table :proposal_statuses do |t|
  9. (...)
  10. end
  11. add_reference :proposals, :proposal_types
  12. add_reference :proposals, :proposal_statuses, :null =>false, :default => 1
  13. end

The corresponding fields (proposal_type_id and proposal_status_id, respectively) will be created in proposals, and the RDBMS will impose a Foreign Key constraint. The references can be removed via remove_reference, i.e., for inclusion in down migrations:
  1. def self.down
  2. remove_reference :proposals, :proposal_types
  3. remove_reference :proposals, :proposal_statuses
  4. drop_table :proposal_statuses
  5. drop_table :proposal_types
  6. drop_table :proposals
  7. end

Of course, in this case the remove_reference call is not really needed - But if you are dropping a table that is referred to from a table that will remain existing, you will have to remove the foreign key constraints (that is, the referring columns).

Join (HABTM) tables

When you define a simple has_and_belongs_to_many (HABTM) relation in your model, you are expected to create an extra table representing this relation. This is a very simple table (i.e. it has only a row for each of the related table‘s IDs), and it carries foreign key constraints.
Please note that join tables are not supposed to carry any extra columns - If you need to add information to join tables, think twice and better use a has_many :elements, :through => :othermodel declaration, and create the othermodel table manually. To create a HABTM table representing that each person can attend many conferences and each conference can be attended by many people:

  1. def self.up
  2. create_table :people do |t|
  3. (...)
  4. end
  5. create_table :conferences do |t|
  6. (...)
  7. end
  8. create_habtm :people, :conferences
  9. end
  10. def self.down
  11. drop_habtm :people, :conferences
  12. drop_table :people
  13. drop_table :conferences
  14. end

The last call will create a conferences_people table (according to Rails' conventions, table names are sorted alphabetically to get the join table‘s name).
Note that in this case, in the down migration, the drop_habtm call must appear before the drop_table calls, as it carries foreign key constraints.

( categories: )

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <br> <b> <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <blockquote> <img> <h1> <h2> <h3> <tt> <pre> <strike>
  • Lines and paragraphs break automatically.
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>. Beside the tag style "<foo>" it is also possible to use "[foo]".

More information about formatting options

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
  ____               __  __          _____   _    
|___ \ _ __ ___ \ \/ / __ _ | ___| | | __
__) | | '_ ` _ \ \ / / _` | | |_ | |/ /
/ __/ | | | | | | / \ | (_| | | _| | <
|_____| |_| |_| |_| /_/\_\ \__, | |_| |_|\_\
|_|
Enter the code depicted in ASCII art style.