2010-10-25 15 views
50

W mojej bazie danych znajdują się nazwy kolumn, takie jak "delete" lub "listen-control" i tak dalej. Nie można ich zmienić, więc chciałbym zmienić nazwy, aby uniknąć problemów w mojej aplikacji.Alias ​​dla nazw kolumn w Railsach

znalazłem the following code ale jest nieaktualny (05 sie 2005) i nie działa z szyn 3:

module Legacy 
    def self.append_features(base) 
    super 
    base.extend(ClassMethods) 
    end 
    module ClassMethods 
    def alias_column(options) 
     options.each do |new_name, old_name| 
     self.send(:define_method, new_name) { self.send(old_name) } 
     self.send(:define_method, "#{new_name}=") { |value| self.send("#{old_name}=", value) } 
     end 
    end 
    end 
end 

ActiveRecord::Base.class_eval do 
    include Legacy 
end 

Jak mogę aliasu nazwy kolumn? Czy to możliwe?

+0

Nie widzę problemu z używaniem "delete" i "listen-control" jako nazw kolumn? Czy napotkasz błąd lub coś innego? – Ariejan

+3

listen-control powoduje problemy, ponieważ w nazwie ma myślnik, co czyni go nieprawidłowym atrybutem obiektu ruby. Ruby zinterpretuje "object.listen-control" jako "object.listen, minus control". A usunięcie może być zastrzeżonym słowem kluczowym. Nie wiem, dlaczego chciałbyś to zrobić. Czasami właściwą odpowiedzią jest zaprzestanie prób walki z rubinem lub szynami. –

+0

'define_method (" listen-control ", Proc.new {puts" bingo "})' then 'send (" listen-control ")'. Gdzie jest problem? – rthbound

Odpowiedz

0

Jak powiedział Jaime, nazwy te mogą powodować problemy.

W takim przypadku użyj rozsądnych nazw. Twój GUI nigdy nie powinien dyktować, jak nazywają się twoje kolumny.

Sugestie: is_deleted lub deleted_at, listen_control

Następnie zmienić widok odpowiednio, to sposób łatwiejsze niż walka ActiveRecord i bazę danych.

+3

... i zmienić główną aplikację, która czyta i zapisuje w bazie danych tylko te nazwy? – user486421

6

Nazwy metod aliasów nie rozwiążą problemu. Jak już wspomniałem w powyższym komentarzu, nie można używać kresek w metodzie ruby ​​lub nazw zmiennych, ponieważ ruby ​​zinterpretuje je jako "minus". tak:

object.listen-control 

będą interpretowane przez rubin jak:

object.listen - control 

i zakończy się niepowodzeniem. Odnaleziony fragment kodu może się nie udać z powodu ruby ​​1.9, a nie z szyn 3. Ruby 1.9 nie pozwala już zadzwonić na .send na metody chronione lub prywatne, jak na przykład 1.8.

Mimo to, rozumiem, że są chwile, kiedy stare nazwy kolumn bazy danych nie wyglądają bardzo ładnie i chcesz je wyczyścić. Utwórz folder w folderze lib o nazwie "bellmyer". Następnie należy utworzyć plik o nazwie „create_alias.rb” i dodać to:

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 

Teraz w modelu, który potrzebuje aliasingu, można to zrobić:

class User < ActiveRecord::Base 
    include Bellmyer::CreateAlias 
    create_alias 'name-this', 'name_this' 
end 

I to alias prawidłowo. Korzysta z metod ActiveRecord w celu uzyskania dostępu do kolumn tabeli bez wywoływania ich jako metod ruby.

+0

Dzięki za odpowiedź, ale testowałem twoje rozwiązanie i otrzymuję komunikat o błędzie: SyntaxError (/usr/lib/ruby/gems/1.9.1/gems/activemodel-3.0.0/lib/active_model/attribute_methods.RB: 229: błąd składni, nieoczekiwany '' send (: vm-password =, * args) ^): gdy zdefiniowane: alias_attribute "vm_password", "VM-hasło" i postarać się „vm_password ". – user486421

+0

Znalazłem rozwiązanie! Zobacz powyższą edycję mojej odpowiedzi. –

+0

Wielkie dzięki! Przetestowałem i znalazłem: 1. W user.rb potrzebuje dodać pierwszą linię: wymaga 'bellmyer/create_alias.rb' 2. Kiedy nikt nie rejestruje w tabeli, twoja metoda działa dobrze. Z jedną lub więcej tablicami rekordów dostaje błąd: ActionView :: Szablon :: Błąd (/usr/lib64/ruby/gems/1.9.1/gems/activemodel-3.0.0/lib/active_model/attribute_methods.rb:273: błąd składni , nieoczekiwane "-", spodziewając się parametru keyword_end undef: vm-password? ... 3. Z nazwą pola, taką jak "delete", ta metoda nie działa, ponieważ "delete" to nazwa metody – user486421

123

Wyraź to w swoim modelu.

alias_attribute :new_column_name, :column_name_in_db 
+0

Ta metoda nie działa, gdy kolumna tabeli ma nazwę zawierającą kreskę. Kolumna tabeli musi być odwzorowana na prawidłową nazwę metody ruby ​​"jak jest", aby móc z niej korzystać. –

+1

czy to działa? 'alias_attribute: 'nazwa nowej kolumny',: 'nazwa kolumny-in-db'' –

+0

:' foo 'jest identyczne z: foo. : "nazwa nowej kolumny" jest symbolem. Przypuszczam, że tego nie próbowałaś. ;) –