Rails ActiveRecord: устаревшая таблица без первичного ключа показывает ноль для результата? - PullRequest
4 голосов
/ 02 ноября 2011

У меня есть приложение Rails, которое будет располагаться поверх устаревшей базы данных с некоторыми ужасными таблицами, с которыми мне приходится иметь дело.Одним из них является таблица feature_attributes, связанная с features.Проблема в том, что эта таблица feature_attributes не имеет первичного ключа.Я не думаю, что это будет проблемой, но, очевидно, это так.У меня есть название моей модели, которое отличается от имени таблицы, но я использую set_table_name, чтобы указать правильное.

class Feature < ActiveRecord::Base
  has_many :feature_attributes
end

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

Как только я загружаю функцию, которая, как я знаю, имеет отношение feature_attributes и назовите feature.feature_attributes, я получу nil.На самом деле, даже FeatureAttribute.first дает мне nil.Результат FeatureAttribute.any? возвращает false.Я обеспокоен тем, что ActiveRecord не читает какие-либо данные из таблицы, потому что нет первичного ключа.Это то, что здесь происходит?

В таблице feature_attribute есть следующие столбцы.

feature_id
attribute_name
attribute_value
created_date
modified_date

Справка!

Я также отмечу, что запусксгенерированный SQL непосредственно на сервере MySQL фактически возвращает мне нужные мне строки.

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

EDIT : Мне очень жаль.В следующий раз я научусь проверять мой database.yml.Очевидно, я читал из тестовой базы данных, в которой была идентичная таблица функций, но таблица feature_attribute была совершенно пустой.

Я чувствую себя идиотом.Спасибо за вашу помощь всем;Я голосую за всех вас за ваши проблемы.Мне понравился ответ каждого.(Могу ли я сам проголосовать?))

Ответы [ 4 ]

5 голосов
/ 02 ноября 2011

Попробуйте также установить первичный ключ:

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

  belongs_to :feature
end

UPDATE

Я думаю, что ваша проблема лежит где-то еще Я только что проверил, и ActiveRecords отлично работает с таблицами без первичного ключа:

Для простой таблицы:

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

      t.timestamps
    end
  end
end

в консоли:

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> 

ОБНОВЛЕНИЕ 2 Не очень хорошо:

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
3 голосов
/ 02 ноября 2011

Если для атрибута определенный атрибут может встречаться только один раз, предполагается, что ключом является attribute_name в сочетании с feature_id. Rails не поддерживает составные первичные ключи "из коробки", но есть гем под названием Composite_primary_keys , который поддерживает именно это.

В вашей модели вы можете написать

set_primary_keys :feature_id, :attribute_name

Если имя атрибута может встречаться несколько раз для одного объекта, комбинация feature_id, attribute_name и attribute_value является ключом, и вы должны написать

set_primary_keys :feature_id, :attribute_name, :attribute_value

Надеюсь, это поможет.

[править] Альтернативный подход:

Выше явно недостаточно, поэтому вы также можете сделать следующее:

class Feature
  has_many :feature_attributes, :finder_sql => 'select * from feature_attributes where feature_id=\'#{id}\''
end

Надеюсь, что это поможет:)

2 голосов
/ 25 ноября 2013
class Feature < ActiveRecord::Base
  self.table_name = 'legacy_table_name'
  self.primary_key = nil
end

Затем выполните запрос, используя Feature.find_by field:'value' или другие запросы ActiveRecord.

1 голос
/ 02 ноября 2011

Если невозможно обновить таблицу, просто добавив первичный ключ автоинкремента, вам лучше справиться с этим вручную:

class Feature < ActiveRecord::Base
  # get rid of has_many feature_attributes and use this instead
  def feature_attributes
    FeatureAttribute.find_by_sql(["select * from feature_attribute where feature_id = ?", self.id])
  end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...