I've loaded (and updated) thousands of these MeteredUsage records. In
the middle of a run, I suddenly get:
ActiveRecord::StatementInvalid: Mysql::Error: Unknown column 'id' in
'where clause': UPDATE `metered_usages` SET `cost` = 12603.46 WHERE `id`
= NULL
I can't see anything that's different about this particular record
compared to its brethren. (Note that I'm invoking this at the console
-- this is not a question about views or controllers.) So the schema
and the model:
It is a pretty fundamental assumption of Active Record that tables
have a primary key. There is (or at least there used to be) a plugin
out there that added support for composite primary keys
It is a pretty fundamental assumption of Active Record that tables
have a primary key. There is (or at least there used to be) a plugin
out there that added support for composite primary keys
Fred
@fred: You may be right, but in that case, the documentation is wrong.
From
:id - Whether to automatically add a primary key column. Defaults
to true. Join tables for has_and_belongs_to_many should set
:id => false.
And, as I hinted at, this IS a join table.
What's interesting is that I cleared the table and rebuilt it -- no
error. When I tried to update the entire table (with identical values),
it gave the same error on the same record. Curiouser and curiouser.
What's interesting is that I cleared the table and rebuilt it -- no
error. When I tried to update the entire table (with identical values),
it gave the same error on the same record. Curiouser and curiouser.
There is nothing courious about it. Rails try to locate particular entry
by means of id, and if it is not there…
Join tables of the habtm variety are just join tables and typically
have no associated model - the assumption is that they are only
manipulated behind the scenes by active record. If you're going do be
doing foo.save! (or foo.update_attributes which calls save) then you
need a primary key, it's just how active record works
My error in terminology -- it's not a join table, but rather a "fact"
table in the Dimensional Database sense. Would it be any different if
this was a HABTM table?
Frederick Cheung wrote:
...If you're going do be
doing foo.save! (or foo.update_attributes which calls save) then you
need a primary key, it's just how active record works
Fred, with all respect, I can't accept your assertion at face value:
I've made thousands of calls to foo.update_attributes on this table, and
only this particular update has triggered the error. There must be
something else going on.
My error in terminology -- it's not a join table, but rather a "fact"
table in the Dimensional Database sense. Would it be any different if
this was a HABTM table?
Frederick Cheung wrote:
> ...If you're going do be
> doing foo.save! (or foo.update_attributes which calls save) then you
> need a primary key, it's just how active record works
Fred, with all respect, I can't accept your assertion at face value:
I've made thousands of calls to foo.update_attributes on this table, and
only this particular update has triggered the error. There must be
something else going on.
So (apologies to Fred) this may be deeper than I thought: How does a
HABTM table EVER get updated? From the Rails 1.9.1
active_record/base.rb sources, update_attributes => save =>
create_or_update => update. The sources for update():
# Updates the associated record with values matching those of the
instance attributes.
# Returns the number of affected rows.
def update(attribute_names = @attributes.keys)
quoted_attributes = attributes_with_quotes(false, false,
attribute_names)
return 0 if quoted_attributes.empty?
connection.update(
"UPDATE #{self.class.quoted_table_name} " +
"SET #{quoted_comma_pair_list(connection, quoted_attributes)}
" +
"WHERE #{connection.quote_column_name(self.class.primary_key)}
= #{quote_value(id)}",
"#{self.class.name} Update"
)
end
Sure enough, it appears to depend on some sort of 'id' -- what is the
primary_key column name for HABTM tables? Or am off in the weeds?
But since you clearly understand better than I do, I'm hoping you can
enlighten me as to how HABTM tables ever get updated? Or how a single
entry in a HABTM table gets deleted (since the delete method, like
update, seems to depend on the existence of an id field)?
So (apologies to Fred) this may be deeper than I thought: How does a
HABTM table EVER get updated? From the Rails 1.9.1
active_record/base.rb sources, update_attributes => save =>
create_or_update => update. The sources for update():
[snip]
Sure enough, it appears to depend on some sort of 'id' -- what is the
primary_key column name for HABTM tables? Or am off in the weeds?
for a normal HABTM there is no corresponding model, so rows never get
updated by this code path. The habtm association generates sql
fragments directly and runs them
Furthermore, because habtm is usually used as a 'dumb' join table,
it's only ever a question of deleting or inserting rows
for a normal HABTM there is no corresponding model, so rows never get
updated by this code path. The habtm association generates sql
fragments directly and runs them
Furthermore, because habtm is usually used as a 'dumb' join table,
it's only ever a question of deleting or inserting rows
Fred
Enlightenment is a slow process, at least for me.
So I think what's going on is that I've created a table that *should* be
declared as HABTM. And now that I think about it in those terms, I'm
not sure why I didn't to that in the first place.
Actually, I think what you want is to use has_many :through
1. add an id to metered_usages
...
Rick -- bingo -- that's what I ended up doing. You probably already
understood that metered_usage needs to carry additional data, so it
couldn't be a pure HABTM table.