2015-04-07 8 views
5

Pytanie o pierwsze ruby ​​/ szyny tutaj. Mam metodę, z której aktualnie korzystam w moim modelu "użytkownika".Metody wielokrotnego użycia w wielu modelach szyn

def generate_token(column) begin self[column] = SecureRandom.urlsafe_base64 end while User.exists?(column => self[column]) end

chcę ponownie wykorzystać tę samą metodę w innym modelu powiedzieć mój model konta.

Gdzie jest dobre miejsce na umieszczenie kodu podobnego do tego, który ma być współdzielony między modelami? Ponadto, aby uzyskać klasę wywołującą, wystarczy użyć "self.class"?

Dzięki

+0

Obawy byłyby konwencją rails, gdzie można umieścić coś takiego, jeśli używasz szyn 4. "self.class" powinno działać dobrze –

Odpowiedz

6

Szyny 4 concerns tutaj do wykonania tej pracy. http://api.rubyonrails.org/classes/ActiveSupport/Concern.html

app/models/user.rb:

class User < ActiveRecord::Base 
    include TokenGenerator 

    def foo 
    $stderr.puts self.class.generate_token("bar") 
    end 
end 

app/models/account.rb:

class Account < ActiveRecord::Base 
    include TokenGenerator 

    class << self 
    def bar 
     return generate_token("foo") 
    end 
    end 
end 

app/models/concerns/token_generator.rb

module TokenGenerator 
    extend ActiveSupport::Concern 

    module ClassMethods 
    def generate_token(c) 
     return "some_thing" 
    end 
    end 
end 
+0

Zakładam, że gdybym chciał zadzwonić to wcześniej, użyłbym tylko: before_create {self.class.generate_token (: activation_token)}? – rmstar25

+1

Będziesz miał to w bloku 'included'. – RPinel

0

dla kodu ponownego użycia, używamy modułów. Bardziej powszechnym użyciem modułów w Railsach jest udostępnianie wspólnego kodu. więc odpowiedź brzmi

  • napisać tę samą metodę w module
  • umieścić go w lib jak lib/some_token_generation.rb

module SomeTokenGeneration def generate_token(column) begin self[column] = SecureRandom.urlsafe_base64 end while User.exists?(column => self[column]) end end

  • potem włączyć ten moduł, w którym modelem chcesz używać , takich jak models/some_model1.rb

class SomeModel1 include SomeTokenGeneration end

lub models/some_model2.rb

class SomeModel2 include SomeTokenGeneration end

include metoda dodaje żadnych metod w module jako metody instancji klasy

Przyjrzyjmy się sytuacji, w której dwie klasy mogłyby dzielić metoda instancji.

Więc można użyć tej metody w obu modelach jak models/some_model1.rb

class SomeModel1 include SomeTokenGeneration def some_method1 self.generate_token(column) end end

lub models/some_model2.rb

class SomeModel2 include SomeTokenGeneration def some_method2 self.generate_token(column) end end

+1

Twoja odpowiedź była właściwa w Railsach <4. Domyślne włączenie biblioteki powodowało błąd kompilacji w złożonych projektach, więc 'obawy 'zostały zaimplementowane w Railsach 4, tylko po to, aby uniknąć umieszczenia kodu do udostępnienia w' lib''s. – pierallard

1

Jeśli kiedykolwiek pisać ten sam sposób dwa razy, masz rację, że jest to prawdopodobnie znak napisania złego kodu. Gdyby to było ja, utworzyłbym klasę abstrakcyjną, która jest klasą nadrzędną dla konta i użytkownika.Ustaw konto i użytkownik dziedziczy po tej klasie nadrzędnej i wstaw całą logikę wspólną do tej klasy nadrzędnej. Następnie Konto i Użytkownik automatycznie uzyskają dostęp do tej wspólnej logiki.

Będziesz chciał sprawdzić, jak tworzyć abstrakcyjne klasy w szynach. Po wprowadzeniu nowej nadrzędnej klasy abstrakcyjnej, upewnij się, że konto użytkownika i dziedziczyć z klasy nadrzędnej zamiast ActiveRecord :: Base tak:

class Account < NewAbstractClass 
end 
class user < NewAbstratClass 
end 

ja nie zgadzając się ani nie zgadzając się z odpowiedziami powyżej lub poniżej, poprzez wykorzystanie problemów lub poprzez użycie modułów. Jest to jednak sposób, w jaki rozwiązałem ten problem wcześniej, i jest to dobry sposób na zorientowanie obiektowe, aby spróbować rozwiązać problem wspólnej logiki między wieloma klasami.

+0

To dobre rozwiązanie, gdy klasa-matka z 2 podklas ma powód do istnienia, tj. Reprezentuje prawdziwą koncepcję. – pierallard

Powiązane problemy