Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails ActiveRecord: legacy table without primary key shows nil for result?

I've got a Rails app that'll be sitting on top of a legacy database with some ugly tables that I'm having to deal with. One is a feature_attributes table related to features. Problem is that this feature_attributes table doesn't have a primary key. I wouldn't think that'd be a problem, but evidently it is. I've got my model name which is different from the table name, but I'm using set_table_name to specify the right one.

class Feature < ActiveRecord::Base
  has_many :feature_attributes
end

class FeatureAttribute < ActiveRecord::Base
  set_table_name 'feature_attribute'
  belongs_to :feature
end

Once I load a feature that I know has related feature_attributes and call feature.feature_attributes on it, I get nil. Matter of fact, even FeatureAttribute.first gives me nil. The result of FeatureAttribute.any? returns false. I'm worried that ActiveRecord isn't reading any of the data from the table because there isn't a primary key. Is that what's going on here?

The feature_attribute table has the following columns.

feature_id
attribute_name
attribute_value
created_date
modified_date

Help!

I'll also note that running the generated SQL directly against the MySQL server actually gets me the rows I want.

SELECT `feature_attribute`.* FROM `feature_attribute` WHERE `feature_attribute`.`feature_id` = 24;

EDIT: I am so sorry. Next time I'll learn to check my database.yml. Evidently I was reading from a test database that had an identical feature table, but the feature_attribute table was totally empty.

I feel like a moron. Thanks for your help, everyone; I'm up voting you all for your troubles. I did like just about everybody's answer. (Can I down vote myself? :))

like image 502
Ben Kreeger Avatar asked Dec 21 '22 07:12

Ben Kreeger


1 Answers

Try to also set the primary key:

class FeatureAttribute < ActiveRecord::Base
  set_table_name 'feature_attribute'
  set_primary_key 'feature_id'

  belongs_to :feature
end

UPDATE

I think your problem lies anywhere else. I just tested and ActiveRecords works fine with tables without a primary key:

For a simple table:

class CreateThings < ActiveRecord::Migration
  def change
    create_table :things, :id => false do |t|
      t.string :name

      t.timestamps
    end
  end
end

in console:

Loading development environment (Rails 3.1.1)
irb(main):001:0> Thing.create(:name=>'A name for the thing')
   (0.1ms)  BEGIN
  SQL (0.3ms)  INSERT INTO `things` (`created_at`, `name`, `updated_at`) VALUES ('2011-11-02 16:33:48', 'A name for the thing', '2011-11-02 16:33:48')
   (40.3ms)  COMMIT
=> #<Thing name: "A name for the thing", created_at: "2011-11-02 16:33:48", updated_at: "2011-11-02 16:33:48">
irb(main):002:0> Thing.first
  Thing Load (0.7ms)  SELECT `things`.* FROM `things` LIMIT 1
=> #<Thing name: "A name for the thing", created_at: "2011-11-02 16:33:48", updated_at: "2011-11-02 16:33:48">
irb(main):003:0> 

UPDATE 2 Not very fine:

irb(main):003:0> Thing.create(:name=>'Another thing')
   (0.2ms)  BEGIN
  SQL (0.4ms)  INSERT INTO `things` (`created_at`, `name`, `updated_at`) VALUES ('2011-11-02 16:40:59', 'Another thing', '2011-11-02 16:40:59')
   (35.4ms)  COMMIT
=> #<Thing name: "Another thing", created_at: "2011-11-02 16:40:59", updated_at: "2011-11-02 16:40:59">
irb(main):004:0> Thing.first
  Thing Load (0.5ms)  SELECT `things`.* FROM `things` LIMIT 1
=> #<Thing name: "A name for the thing", created_at: "2011-11-02 16:33:48", updated_at: "2011-11-02 16:33:48">
irb(main):005:0> Thing.last
  Thing Load (11.8ms)  SELECT `things`.* FROM `things` ORDER BY `things`.`` DESC LIMIT 1
Mysql2::Error: Unknown column 'things.' in 'order clause': SELECT  `things`.* FROM `things`  ORDER BY `things`.`` DESC LIMIT 1
ActiveRecord::StatementInvalid: Mysql2::Error: Unknown column 'things.' in 'order clause': SELECT  `things`.* FROM `things`  ORDER BY `things`.`` DESC LIMIT 1
like image 152
Ion Br. Avatar answered Apr 08 '23 03:04

Ion Br.