2012-08-16 11 views
39

Chcę dodać do istniejącego modelu niektóre atrybuty, które nie muszą być utrwalone, a nawet zmapowane do kolumny bazy danych. Czy istnieje rozwiązanie, aby określić takie rzeczy?Nietrwałe atrybuty modelu ActiveRecord

+0

Prawdopodobny duplikat [Dodawanie dodatkowych atrybutów czasu pracy do obiektu activerecord] (http://stackoverflow.com/questions/7584592/adding-extra-run-time-attribs-to-an-activerecord-object) – mlt

Odpowiedz

48

Oczywiście użyj dobrego starego rubinu o nazwie attr_accessor. W modelu:

attr_accessor :foo, :bar 

Będziesz mógł robić:

object.foo = 'baz' 
object.foo #=> 'baz' 
+14

Jak zdobyć ten atrybut w formacie JSON obiektu? Powiedzmy, chcę, aby ten atrybut pojawił się w JSON obiektu po stronie klienta. Czy to dostanę? od tej chwili nie otrzymuję tego, mimo że ustawiłem to w mojej metodzie tworzenia. Jak to zrobić? – Yash

+0

A w Railsach 4? – monteirobrena

+1

@monteirobrena samo – apneadiving

26

miałem ten sam problem, ale ja potrzebowałem bootstrap modelu, więc atrybut musiał utrzymywać się po to_json nazwano . Musisz zrobić jedną dodatkową rzecz.

Jak stwierdził apneadiving, najprostszym sposobem na rozpoczęcie jest, aby przejść do danego modelu i dodać:

attr_accessor :foo 

Następnie można przypisać atrybuty. Aby jednak atrybut się przykleił, musisz zmienić metodę atrybutów. W pliku modelu dodaj tę metodę:

def attributes 
    super.merge('foo' => self.foo) 
end 
1

W moim przypadku chciałem użyć lewego sprzężenia do wypełnienia niestandardowego atrybutu. Działa, jeśli nie dodaję niczego, ale chcę też móc ustawić atrybut na nowym obiekcie i oczywiście go nie ma. Jeśli dodaję attr_accessor, zawsze po nil po select następuje powrót. Oto podejście, w którym znalazłem podejście do ustawiania nowego obiektu i pobierania z lewego sprzężenia.

after_initialize do 
    self.foo = nil unless @attributes.key?("foo") 
end 

def foo 
    @attributes["foo"] 
end 

def foo=(value) 
    @attributes["foo"] = value 
end 
+0

Nie działa już w Railsach 4.2. '@ attributes' jest teraz' ActiveRecord :: AttributeSet', który obsługuje '[]' ale nie '[] ='. – davogones

5

W przypadku gdy ktoś zastanawia się, jak czynią to na widoku, użyj argumentów metoda metody renderowania, tak:

render json: {results: results}, methods: [:my_attribute] 

Należy wiedzieć, że to działa tylko wtedy, gdy ustawienie attr_accessor na modelu i ustaw atrybut w akcji kontrolera, tak jak wyjaśniono wybraną odpowiedź.

Powiązane problemy