2012-08-15 12 views
5

Mam modele Kategoria i produkty. Jeśli użyję category.products << new_product element zostanie dodany do tablicy, a rekord zostanie zapisany w bazie danych. Próbowałem dodać następującą metodę "add" do klasy tablic i podczas gdy ona dodaje nowy_produkt do tablicy, nie zapisuje go do bazy danych. Dlaczego?Dodawanie metody Dodaj do tablicy ActiveRecord

class Array 
    def add(item) 
    self << item 
    end 
end 

Aktualizacja:

collection_proxy.rb ma następujący sposób:

def <<(*records) 
    proxy_association.concat(records) && self 
end 
alias_method :push, :<< 

Więc następujące rozszerzenie działa:

class ActiveRecord::Relation 
    def add(*records) 
    proxy_association.concat(records) && self 
    end 
end 

Rozwiązanie:

Dodaj alias do CollectionProxy:

class ActiveRecord::Associations::CollectionProxy 
    alias_method :add, :<< 
end 
+0

Ponieważ Szyny stowarzyszenia nie są tablice, po prostu twierdzą, że są . –

+0

Czym one są wtedy? jak mogę dodać metodę "Dodaj"? – Manuel

Odpowiedz

2

Edit: Manuel znaleźć lepsze rozwiązanie

class ActiveRecord::Associations::CollectionProxy 
    alias_method :add, :<< 
end 

Oryginalne rozwiązanie:

To powinno Ci zacząć. To nie jest doskonałe.

class ActiveRecord::Relation 
    def add(attrs) 
    create attrs 
    end 
end 

Zamiast odpalić nowy projekt szynach z nazwami modeli, po prostu stosować jeden miałem na poniższym przykładzie:

1.9.3p194 :006 > Artist.create(:first_name => "Kyle", :last_name => "G", :email => "[email protected]") 
=> #<Artist id: 5, first_name: "Kyle", last_name: "G", nickname: nil, email: "[email protected]", created_at: "2012-08-16 04:08:30", updated_at: "2012-08-16 04:08:30", profile_image_id: nil, active: true, bio: nil> 
1.9.3p194 :007 > Artist.first.posts.count 
=> 0 
1.9.3p194 :008 > Artist.first.posts.add :title => "Foo", :body => "Bar" 
=> #<Post id: 12, title: "Foo", body: "Bar", artist_id: 5, created_at: "2012-08-16 04:08:48", updated_at: "2012-08-16 04:08:48"> 
1.9.3p194 :009 > Artist.first.posts.count 
=> 1 
+0

Dzięki. Czy wiesz, dlaczego nie powiedzie się, gdy dodasz nowy rekord nie jako skrót, ale przekazując obiekt? (Otrzymuję "NoMethodError: undefined method" stringify_keys "") – Manuel

+0

@Manuel tak, 'add' wywołuje' create' i oczekuje atrybutów jako hash. Możesz zmienić metodę na coś w stylu 'create item.attributes', ale możesz mieć problemy z chronionymi atrybutami. Rozważ wybranie tych, których potrzebujesz od obiektu. – Kyle

+0

Niezupełnie :(create item.attributes tworzy rekord w bazie danych, ale nie tworzy relacji (w twoim przypadku artist_id ma wartość null) – Manuel