Sean C. wrote:
If anybody could be so kind as to quickly tell me, in the following
table declaration (from the pickaxe book):
what is “fk_items_product”? I can’t find any previous mention of it.
Which leads me to believe it’s like an id for the foreign key.
That is correct. Basically it defines a constraint at the database
level that makes sure the foreign key is valid.
The reason that it has a separate name is that one name describes the
data, while another name describes the constraint. Here, ‘product_id’
is the name of the actual column that contains the foreign key IDs –
the data. And ‘fk_items_product’ is the name for the whole concept of
that database-level constraint, rather than any specific bit of data.
So, in the future, if you decided that you didn’t need the database to
enforce that constraint for you anymore, you would say something like
“get rid of the constraint called ‘fk_items_product’”. However, the
data column ‘product_id’ would still exist, and there’d be nothing
stopping you from continuing to use that data to link a product with a
line item.
In fact, one of the conventions of Rails is not to bother with
constraints at the database level, and just let Rails handle it all for
you. (This is a bit of a bone of contention, as some people like the
safety net of database-level constraints. But they’re not strictly
necessary, and the Rails convention is not to use them.)
If I were you, I would not worry about learning about database-level
foreign key constraints, apart from having a rough idea about what they
are. You don’t need them to use associations in Rails.
So in this case, you could leave out the constraint definition
entirely, and as far as Rails is concerned nothing would be different:
create table line_items (
id int not null auto_increment,
product_id int not null,
quantity int not null default 0,
unit_price decimal(10,2) not null,
primary key (id)
);
In fact, the preferred method of defining tables these days is to use
migrations. This is a way of specifying your database changes in Ruby,
so that they can be run automatically against any database. The above
table could be defined in a migration with something like:
create_table :line_items do |t|
t.column :product_id, :integer
t.column :quantity, :integer
t.column :unit_price, :float
end
For more about migrations, see
But that
sounds redundant, since you’re setting up “product_id” to pull its value
from the other table already.
But if it is, then which one do we use? Would we use
“line_items.product_id”, or “line_items.fk_items_product” to get the
value we want?
You’d use ‘line_items.product_id’, since that’s where the foreign key
data lives. As described above, ‘fk_items_product’ doesn’t really
‘contain’ the foreign key data; all it is is a ‘rule’ that keeps an eye
on the foreign key column.
Also, would there be any other steps afterwards besides declaring the
relationship of the two tables in the model?
Nope, that’s it.
Chris