Устаревшая таблица со столбцом с именем «class» в Rails - PullRequest
9 голосов
/ 28 октября 2010

У меня есть устаревшая таблица, которую мое приложение rails делит с другим приложением. У него есть столбец под названием «класс». При первой ссылке на какой-либо атрибут в этой модели я получаю сообщение об ошибке. Последующие ссылки на атрибуты работают. Есть хороший обходной путь для этого, или я должен просто изменить другое приложение, которое использует эту таблицу (тьфу)?

>> Member::Ssg.find(:first)
 => #<Member::Ssg ssg_key: #<BigDecimal:10b169688,'0.253E3',4(8)>, org_id: 2, academic_year: 2006, class: true, next_due_date: "2011-06-01", submitted_date: "2006-02-13", notes: nil, owner_id: "1">
 >> Member::Ssg.find(:first).notes
 NoMethodError: undefined method `generated_methods' for true:TrueClass
        from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/attribute_methods.rb:247:in `method_missing'
        from (irb):2
>> Member::Ssg.find(:first).notes
=> nil

РЕШЕНИЕ: Я выбрал комбинацию решения Bellmyer и добавил приведенный ниже код к моей модели

 class << self
   def instance_method_already_implemented?(method_name)
     return true if method_name == 'class'
     super
   end
 end

1 Ответ

9 голосов
/ 28 октября 2010

ПРИМЕЧАНИЕ: Пожалуйста, ознакомьтесь с обновленным решением в конце этого ответа.Оставляя оригинальное устаревшее решение по историческим причинам.

Это встречается достаточно часто (устаревшие имена столбцов, взаимодействующие с ruby ​​/ rails), что я мог бы просто сделать из этого плагин.Вот как вы можете это исправить сразу же.Создайте этот файл в своем приложении:

# lib/bellmyer/create_alias.rb
module Bellmyer
  module CreateAlias
    def self.included(base)
      base.extend CreateAliasMethods
    end

    module CreateAliasMethods
      def create_alias old_name, new_name
        define_method new_name.to_s do
          self.read_attribute old_name.to_s
        end

        define_method new_name.to_s + "=" do |value|
          self.write_attribute old_name.to_s, value
        end
      end
    end
  end
end

А теперь в вашей модели:

class Member < ActiveRecord::Base
  include Bellmyer::CreateAlias
  create_alias 'class', 'class_name'
end

Первый параметр create_alias - это имя старого метода, а второй - новыйимя, которое вы хотите назвать, это не будет мешать рельсам.В основном он использует методы read_attribute и write_attribute для взаимодействия со столбцом вместо методов ruby, которые определяются ActiveRecord.Просто обязательно используйте новое имя для поля везде, например так:

member.class_name = 'helper'

Это работает с ruby ​​1.8, но я еще не тестировал с ruby ​​1.9.Надеюсь, это поможет!

ОБНОВЛЕНИЕ: Я нашел лучшее решение, которое работает в Rails 3, гем safe_attributes.Я написал сообщение в блоге, объясняющее, как его использовать, с примерами фрагментов кода и полным примером приложения, которое вы можете скачать с github и поиграть с ним.Вот ссылка:

Старые имена столбцов базы данных в Rails 3

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...