2010-05-22 4 views
1

У меня есть модель User и когда я создаю один, я хочу, чтобы прагматично установки некоторых ключей API, а что нет, а именно:
@user.apikey = Digest::MD5.hexdigest(BCrypt::Password.create("jibberish").to_s)Как установить стандартные атрибуты в модели рубинового

Я хочу, чтобы иметь возможность запустите User.create!(:email=>"[email protected]") и создайте пользователя со случайно созданным ключом API и секретным.

В настоящее время я делаю это в контроллере, но когда я попытался добавить пользователя по умолчанию в файл seeds.rb, я получаю ошибку SQL (говоря, что мой apikey имеет значение null).

Я попытался переопределить определение save, но это вызвало проблемы, когда я обновил модель, потому что она переопределит значения. Я попытался переопределить определение initialize, но это возвращает nil:NilClass и сломал вещи.

Есть ли лучший способ сделать это?

ответ

4

использовать обратные вызовы и || = (= если объект не равен нулю) :)

class User < ActiveRecord::Base 
    before_create :add_apikey #or before_save 

    private 
    def add_apikey 
    self.apikey ||= Digest::MD5.hexdigest(BCrypt::Password.create(self.password).to_s) 
    end 
end 

но вы обязательно должны взглянуть на devise, authlogic или clearance драгоценных камней

+0

Я думаю, что 'before_create' может быть хорошим, но если он проверяет присутствие apikey, ему нужно будет сделать это в' before_validation'. – theIV

+0

Если я делаю 'User.new (params)', то '@ user.save' является запуском фильтра' before_create'? –

+0

Да, потому что сохранение действительно действует как созданный в этом случае, поскольку '@ user.new_record?' Вернет true. – theIV

1

Что делать, если в вашем определении save вы проверяете, apikey является nil, и если да, то вы его установили?

+0

Выполняется ли 'save' def при запуске' create! '? (Извините, ruby ​​noob) –

0
class User 
    def self.create_user_with_digest(:options = { }) 
     self.create(:options) 
     self.apikey = Digest::MD5.hexdigest(BCrypt::Password.create("jibberish").to_s) 
     self.save 
     return self 
    end 
end 

Тогда вы можете позвонить User.create_user_with_digest (: имя => «боб») и вы получите дайджеста автоматически создается и присваивается пользователю, Вы, вероятно, хотите, чтобы сгенерировать ключ ИПН с другой библиотеке, чем MD5, такой как SHA256, вы также должны, вероятно, поместить какое-то пользовательское поле ввода, постоянно увеличивающееся число (например, текущее время) и соль.

Надеется, что это помогает

1

Посмотри ActiveRecord::Callbacks & в частности before_validation.

+0

То, что я пытаюсь сделать, это передать электронное письмо новому объекту пользователя, а затем создать его. Я хочу, чтобы сама модель создавала APIkey и секрет, так что в любое время, когда я создаю пользователя, я знаю, что ключ API будет там. –

+0

Я понимаю это. Моя точка в комментарии к ответу Тадаса заключается в том, что если вы не принимаете Пользователей, у которых нет apikey, вам нужно сделать это before_validation, а не before_create, потому что before_create происходит после проверки. – theIV

0

Я считаю, что это работает. .. просто поместите метод в ваш model.

def apikey=(value) 
    self[:apikey] = Digest::MD5.hexdigest(BCrypt::Password.create("jibberish").to_s) 
end 
+0

Мне все еще нужно иметь возможность заполнять пользователя из базы данных, в которой хранится APIkey ... будет ли это решение присутствовать проблема, когда я по существу пытаюсь присвоить значение функции? –