2015-02-10 39 views
2

我有一个引擎,调用Xaaron。和一个名为core_models的Gem。我试图将Xaaron的用户模型作为一个实验移动到宝石中。最终我希望将引擎中的所有模型转移到宝石中。移动模型成宝石 - 的Rails 4.1

这是我做什么,创业板lib/core_models/models/user.rb下我做:

require_relative 'concerns/user_concerns' 
require 'bcrypt' 

module CoreModels 
    module Models 
    class User < ActiveRecord::Base 

     extend FriendlyId 
     friendly_id :first_name, use: [:slugged, :finders, :history] 

     before_save :encrypt_password 

     has_many :group_memberships, :dependent => :delete_all 
     has_many :groups, :through => :group_memberships, :dependent => :delete_all 
     has_many :roles, :through => :group_memberships, :dependent => :delete_all 

     has_many :api_keys 

     validates :first_name, presence: true 
     validates :user_name, uniqueness: true, presence: true, length: {minimum: 5} 
     validates :email, presence: true, confirmation: true, uniqueness: true 
     validates_format_of :email, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i 
     validates :password, presence: true, confirmation: true, length: { minimum: 10 }, if: :new_record? 

     include CoreModels::Models::Concerns::UserConcerns 

     before_create{ generate_token(:auth_token) } 

     def self.authenticate_user(user_name, password) 
     user = Xaaron::User.find_by_user_name(user_name) 
     if(user && (user.password == BCrypt::Engine.hash_secret(password, user.salt))) 
      user 
     else 
      nil 
     end 
     end 

     def encrypt_password 
     if password.present? 
      self.salt = BCrypt::Engine.generate_salt 
      self.password = BCrypt::Engine.hash_secret(password, salt) 
     end 
     end 

     def send_password_reset 
     generate_token(:password_reset_token) 
     self.password_reset_timestamp = Time.zone.now 
     save! 
     UserMailer.password_reset(self).deliver 
     end 

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

这是用来在Xaaron模型。

在Xaaron引擎,app/models/xaaron/user.rb下我做:

require 'core_models/models/user' 

module Xaaron 
    class User < CoreModels::Models::User 
    end 
end 

正如你看到的,我只是扩展模型。

现在,我认为这会工作,显然它不会因为任何与所有的用户模型交互时抛出,测试明智:

Failure/Error: create_login_admin_user 
ActiveRecord::StatementInvalid: 
    PG::UndefinedTable: ERROR: relation "users" does not exist 
    LINE 5:    WHERE a.attrelid = '"users"'::regclass 
              ^
    :    SELECT a.attname, format_type(a.atttypid, a.atttypmod), 
         pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod 
        FROM pg_attribute a LEFT JOIN pg_attrdef d 
        ON a.attrelid = d.adrelid AND a.attnum = d.adnum 
        WHERE a.attrelid = '"users"'::regclass 
        AND a.attnum > 0 AND NOT a.attisdropped 
        ORDER BY a.attnum 

现在Xaaron的表是名间隔到的xaaron_table_names,所以在这种情况下,它的xaaron_users

我认为它仍然知道如何看看xaaron_users表,即使我扩展了另一个模型。显然不是。

我能做些什么来纠正这使我的模型仍然是创业板,但通过访问或xaaron任何其他应用程序,或不名称空间中存在的表?

回答

1

这不会使用xaaron_users表,因为CoreModels::Model::User不在Xaaron名称空间之内,因此在您的表名中不会有xaaron_前缀。

的解决方案是手动指定模型内的表名:

module Xaaron 
    class User < CoreModels::Models::User 
    self.table_name = "xaaron_users" 
    end 
end