Rails System Wide Уникальный идентификатор

Я работаю над приложением Rails 4 и хочу, чтобы каждая запись в моем приложении rails автоматически создавалась при создании. я использую SecureRandom.urlsafe_base64(7, false) создать идентификатор. Я прочитал вокруг, и я решил создать свой собственный active_record.rb config/initializer для автоматического создания идентификаторов. В active_record.rb у меня есть

module UniqueID
  extend ActiveSupport::Concern

  self.primary_key = 'unique_id'
  before_create :set_unique_id

  protected

  def set_unique_id
    loop do
      self.unique_id = SecureRandom.urlsafe_base64(7, false)
      break unless self.find_by_unique_id(self.unique_id)
    end
  end
end

ActiveRecord::Base.send(:include, UniqueID)

но когда я запускаю БД: мигрирую, я получаю

Couldn't create database for {"adapter"=>"postgresql", "encoding"=>"unicode", "database"=>"myapp_test", "pool"=>5, "username"=>"myapp", "password"=>nil}
rake aborted!
undefined method `primary_key=' for UniqueID:Module
/Users/me/RubymineProjects/myapp/config/initializers/active_record.rb:4:in `<module:UniqueID>'
/Users/me/RubymineProjects/myapp/config/initializers/active_record.rb:1:in `<top (required)>'
/Users/me/.rvm/gems/ruby-2.0.0-p195/gems/activesupport-4.0.0.rc2/lib/active_support/dependencies.rb:222:in `load'
/Users/me/.rvm/gems/ruby-2.0.0-p195/gems/activesupport-4.0.0.rc2/lib/active_support/dependencies.rb:222:in `block in load'
/Users/me/.rvm/gems/ruby-2.0.0-p195/gems/activesupport-4.0.0.rc2/lib/active_support/dependencies.rb:213:in `load_dependency'
/Users/me/.rvm/gems/ruby-2.0.0-p195/gems/activesupport-4.0.0.rc2/lib/active_support/dependencies.rb:222:in `load'
/Users/me/.rvm/gems/ruby-2.0.0-p195/gems/railties-4.0.0.rc2/lib/rails/engine.rb:609:in `block (2 levels) in <class:Engine>'
/Users/me/.rvm/gems/ruby-2.0.0-p195/gems/railties-4.0.0.rc2/lib/rails/engine.rb:608:in `each'
/Users/me/.rvm/gems/ruby-2.0.0-p195/gems/railties-4.0.0.rc2/lib/rails/engine.rb:608:in `block in <class:Engine>'
/Users/me/.rvm/gems/ruby-2.0.0-p195/gems/railties-4.0.0.rc2/lib/rails/initializable.rb:30:in `instance_exec'
/Users/me/.rvm/gems/ruby-2.0.0-p195/gems/railties-4.0.0.rc2/lib/rails/initializable.rb:30:in `run'
/Users/me/.rvm/gems/ruby-2.0.0-p195/gems/railties-4.0.0.rc2/lib/rails/initializable.rb:55:in `block in run_initializers'
/Users/me/.rvm/gems/ruby-2.0.0-p195/gems/railties-4.0.0.rc2/lib/rails/initializable.rb:44:in `each'
/Users/me/.rvm/gems/ruby-2.0.0-p195/gems/railties-4.0.0.rc2/lib/rails/initializable.rb:44:in `tsort_each_child'
/Users/me/.rvm/gems/ruby-2.0.0-p195/gems/railties-4.0.0.rc2/lib/rails/initializable.rb:54:in `run_initializers'
/Users/me/.rvm/gems/ruby-2.0.0-p195/gems/railties-4.0.0.rc2/lib/rails/application.rb:215:in `initialize!'
/Users/me/.rvm/gems/ruby-2.0.0-p195/gems/railties-4.0.0.rc2/lib/rails/railtie/configurable.rb:30:in `method_missing'
/Users/me/RubymineProjects/myapp/config/environment.rb:5:in `<top (required)>'
/Users/me/.rvm/gems/ruby-2.0.0-p195/gems/activesupport-4.0.0.rc2/lib/active_support/dependencies.rb:228:in `require'
/Users/me/.rvm/gems/ruby-2.0.0-p195/gems/activesupport-4.0.0.rc2/lib/active_support/dependencies.rb:228:in `block in require'
/Users/me/.rvm/gems/ruby-2.0.0-p195/gems/activesupport-4.0.0.rc2/lib/active_support/dependencies.rb:213:in `load_dependency'
/Users/me/.rvm/gems/ruby-2.0.0-p195/gems/activesupport-4.0.0.rc2/lib/active_support/dependencies.rb:228:in `require'
/Users/me/.rvm/gems/ruby-2.0.0-p195/gems/railties-4.0.0.rc2/lib/rails/application.rb:189:in `require_environment!'
/Users/me/.rvm/gems/ruby-2.0.0-p195/gems/railties-4.0.0.rc2/lib/rails/application.rb:249:in `block in run_tasks_blocks'
/Users/me/.rvm/gems/ruby-2.0.0-p195@global/gems/rake-10.0.4/lib/rake/task.rb:246:in `call'
/Users/me/.rvm/gems/ruby-2.0.0-p195@global/gems/rake-10.0.4/lib/rake/task.rb:246:in `block in execute'
/Users/me/.rvm/gems/ruby-2.0.0-p195@global/gems/rake-10.0.4/lib/rake/task.rb:241:in `each'
/Users/me/.rvm/gems/ruby-2.0.0-p195@global/gems/rake-10.0.4/lib/rake/task.rb:241:in `execute'
/Users/me/.rvm/gems/ruby-2.0.0-p195@global/gems/rake-10.0.4/lib/rake/task.rb:184:in `block in invoke_with_call_chain'
/Users/me/.rvm/gems/ruby-2.0.0-p195@global/gems/rake-10.0.4/lib/rake/task.rb:177:in `invoke_with_call_chain'
/Users/me/.rvm/gems/ruby-2.0.0-p195@global/gems/rake-10.0.4/lib/rake/task.rb:205:in `block in invoke_prerequisites'
/Users/me/.rvm/gems/ruby-2.0.0-p195@global/gems/rake-10.0.4/lib/rake/task.rb:203:in `each'
/Users/me/.rvm/gems/ruby-2.0.0-p195@global/gems/rake-10.0.4/lib/rake/task.rb:203:in `invoke_prerequisites'
/Users/me/.rvm/gems/ruby-2.0.0-p195@global/gems/rake-10.0.4/lib/rake/task.rb:183:in `block in invoke_with_call_chain'
/Users/me/.rvm/gems/ruby-2.0.0-p195@global/gems/rake-10.0.4/lib/rake/task.rb:177:in `invoke_with_call_chain'
/Users/me/.rvm/gems/ruby-2.0.0-p195@global/gems/rake-10.0.4/lib/rake/task.rb:205:in `block in invoke_prerequisites'
/Users/me/.rvm/gems/ruby-2.0.0-p195@global/gems/rake-10.0.4/lib/rake/task.rb:203:in `each'
/Users/me/.rvm/gems/ruby-2.0.0-p195@global/gems/rake-10.0.4/lib/rake/task.rb:203:in `invoke_prerequisites'
/Users/me/.rvm/gems/ruby-2.0.0-p195@global/gems/rake-10.0.4/lib/rake/task.rb:183:in `block in invoke_with_call_chain'
/Users/me/.rvm/gems/ruby-2.0.0-p195@global/gems/rake-10.0.4/lib/rake/task.rb:177:in `invoke_with_call_chain'
/Users/me/.rvm/gems/ruby-2.0.0-p195@global/gems/rake-10.0.4/lib/rake/task.rb:170:in `invoke'
/Users/me/.rvm/gems/ruby-2.0.0-p195@global/gems/rake-10.0.4/lib/rake/application.rb:143:in `invoke_task'
/Users/me/.rvm/gems/ruby-2.0.0-p195@global/gems/rake-10.0.4/lib/rake/application.rb:101:in `block (2 levels) in top_level'
/Users/me/.rvm/gems/ruby-2.0.0-p195@global/gems/rake-10.0.4/lib/rake/application.rb:101:in `each'
/Users/me/.rvm/gems/ruby-2.0.0-p195@global/gems/rake-10.0.4/lib/rake/application.rb:101:in `block in top_level'
/Users/me/.rvm/gems/ruby-2.0.0-p195@global/gems/rake-10.0.4/lib/rake/application.rb:110:in `run_with_threads'
/Users/me/.rvm/gems/ruby-2.0.0-p195@global/gems/rake-10.0.4/lib/rake/application.rb:95:in `top_level'
/Users/me/.rvm/gems/ruby-2.0.0-p195@global/gems/rake-10.0.4/lib/rake/application.rb:73:in `block in run'
/Users/me/.rvm/gems/ruby-2.0.0-p195@global/gems/rake-10.0.4/lib/rake/application.rb:160:in `standard_exception_handling'
/Users/me/.rvm/gems/ruby-2.0.0-p195@global/gems/rake-10.0.4/lib/rake/application.rb:70:in `run'
-e:1:in `load'
-e:1:in `<main>'
Tasks: TOP => db:migrate:reset => db:migrate => environment
(See full trace by running task with --trace)

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

Обновление: при использовании включить я тогда получаю:

rake aborted!
An error has occurred, this and all later migrations canceled:

undefined method `unique_id=' for #<ActiveRecord::SchemaMigration version: "20130623171324">

миграция

class AddUniqueIdToUsers < ActiveRecord::Migration
  def change
    add_column :users, :unique_id, :string
  end
end

2 ответа

Решение

Я думаю, вы должны переместить логику внутри включенного блока? Как это

included do
  self.primary_key = 'unique_id'
  before_create :set_unique_id
end

-- РЕДАКТИРОВАТЬ --

Вы также можете попробовать изменить метод на

def set_unique_id
  loop do
    self.id = SecureRandom.urlsafe_base64(7, false)
    break unless self.find(self.id)
  end
end

Заворачивая это в included блок должен работать. Вот так:

included do
  primary_key = 'unique_id'
  before_create :set_unique_id
end
Другие вопросы по тегам