2010-10-28 8 views
9

Mam starszą tabelę, którą moja aplikacja szynowa współdzieli z inną aplikacją. Ma kolumnę o nazwie "klasa". Za pierwszym razem, gdy odwołuję się do dowolnego atrybutu w tym modelu, pojawia się błąd. Późniejsze odwołania do atrybutów działają. Czy istnieje dobre obejście tego problemu, czy powinienem po prostu zmodyfikować inną aplikację korzystającą z tej tabeli (ugh)?Wcześniejszy stół z kolumną o nazwie "klasa" w Railsach

>> 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 

ROZWIĄZANIE: poszedłem z kombinacji roztworze Bellmyer i dodając poniższy kod do mojego modelu

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

prostu chcę powiedzieć, że zaktualizowane rozwiązanie działało świetnie. Dziękuję Ci! –

+0

@JustinHoldsclaw, czy próbowałeś tego na Railsach 4 lub 5? –

+0

@ MahmoudM.Abdel-Fattah to było na Railsach 4.2 –

Odpowiedz

9

UWAGA: Proszę zobaczyć zaktualizowaną rozwiązanie na końcu tej odpowiedzi. Pozostawienie oryginalnego przestarzałego rozwiązania z przyczyn historycznych.

To pojawiało się dość często (starsze nazwy kolumn kolidowały z rubinami/szynami), że mogę po prostu zrobić z tego wtyczkę. Oto jak możesz to naprawić od razu. Utworzyć ten plik w aplikacji:

# 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 

i teraz, w modelu:

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

Pierwszym parametrem create_alias jest stara nazwa metody, a drugi parametr to nowa nazwa chcesz nazwij to, że nie będzie przeszkadzać w szynach. Zasadniczo stosuje metody read_attribute i write_attribute do interakcji z kolumną zamiast z metodami ruby, które są definiowane przez ActiveRecord. Tylko pamiętaj, aby używać nowej nazwy w polu wszędzie, tak jak poniżej:

member.class_name = 'helper' 

To działa z Ruby 1.8, ale nie testowałem z Ruby 1.9 jeszcze. Mam nadzieję, że to pomoże!

AKTUALIZACJA: Znalazłem lepsze rozwiązanie, które działa w Rails 3, klejnotach safe_attributes. Napisałem post na blogu wyjaśniający, jak go używać, z przykładowymi fragmentami kodu i pełną przykładową aplikacją, którą można pobrać z github i bawić się z nią. Oto link:

Legacy Database Column Names in Rails 3

+1

To nie wystarczy. To pozwala mi odwołać się do wartości kolumny klasy, ale nadal idę do błędu NoMethodError: undefined metoda 'generated_methods 'dla true: TrueClass z /Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/ active_record/attribute_methods.rb: 247: in 'method_missing ' od (irb): 2 – Anna

+0

Zaktualizowałem swoją odpowiedź za pomocą działającego rozwiązania. –

Powiązane problemy