2015-04-07 4 views
5

Здесь вы можете задать вопрос начинающему рубину/рельсу. У меня есть метод, который я использую в моей модели «Пользователь».Способы повторного использования в нескольких моделях Rails

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

Я хочу использовать тот же метод в другой модели сказать, моя модель счета.

Где хорошее место для размещения кода, подобного этому, между моделями? Кроме того, чтобы получить вызывающий класс, я просто использую «self.class»?

Благодаря

+0

Озабоченность была бы соглашением по рельсам, где можно было бы поместить что-то вроде этого, если вы используете рельсы 4. 'self.class' должен работать нормально –

ответ

6

Rails 4 concerns здесь, чтобы сделать эту работу. 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

Я предполагаю, что если бы я хотел вызвать это в before_, я бы просто использовал: before_create {self.class.generate_token (: activation_token)}? – rmstar25

+1

У вас есть это в блоке 'included'. – RPinel

0

Для повторного использования кода, мы используем модули. Более распространенное использование модулей в Rails заключается в совместном использовании общего кода. поэтому ответ

  • написать один и тот же метод в модуле
  • место его в Lib как 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

  • после этого включить этот модуль, в котором модель вы хотите для использования , как models/some_model1.rb

class SomeModel1 include SomeTokenGeneration end

или models/some_model2.rb

class SomeModel2 include SomeTokenGeneration end

включаемой метод добавляет любые методы в модуле как методы экземпляра в классе

Давайте посмотрим на сценарий, в котором два класса может поделиться метод экземпляра.

Таким образом, вы можете использовать этот метод в обеих моделях, как models/some_model1.rb

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

или models/some_model2.rb

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

+1

Ваш ответ был прав в Rails <4. Включение библиотеки по умолчанию вызвало ошибку компиляции для сложных проектов, поэтому «соображения» были реализованы в Rails 4, просто для того, чтобы исключить совместный код в «lib». – pierallard

1

Если вы когда-либо писать один и тот же метод дважды, вы правы, что это вероятно, признак написания плохого кода. Если бы это был я, я бы создал абстрактный класс, который является родительским классом как для Пользователя, так и для Пользователя.Сделайте Учетную запись и Пользователь наследованы от этого родительского класса и поместите всю общую логику в этот родительский класс. Затем учетная запись и пользователь автоматически получат доступ к этой общей логике.

Вы хотите посмотреть, как сделать абстрактные классы в рельсах. После того, как вы сделали новый родительский абстрактный класс, убедитесь, что учетная запись пользователя и наследовать от родительского класса вместо ActiveRecord :: Base, как так:

class Account < NewAbstractClass 
end 
class user < NewAbstratClass 
end 

Я ни согласования, ни несогласия с указанными выше или ниже ответов, используя проблемы или используя модули. Тем не менее, именно так я решил эту проблему раньше в прошлом, и это хороший объектно-ориентированный способ попытаться решить проблему общей логики между несколькими классами.

+0

Это хорошее решение, когда у матери-класса 2 подкласса есть основания для существования, т. Е. Он представляет собой истинную концепцию. – pierallard

Смежные вопросы