我在Rails 3中使用Devise,并且在rails中有一个用户模型开始变得有点拥挤..所以我想将所有登录meethods放在一个模块中并从我的模型中包含它们。我正在尝试这样的事情:
应用程序/模型/ user.rb
class User < ActiveRecord::Base
include UserImageable
extend Loginable
has_one :profile, :dependent => :destroy
has_many :items, :dependent => :destroy
has_many :products, :through => :items
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me, :first_name, :last_name, :phone_number, :location, :photo, :profile_attributes, :access_token
delegate :first_name, :last_name, :phone_number, :phone_number=, :location, :location=, :photo, :to => :profile
accepts_nested_attributes_for :profile
end
和
LIB /自动加载/ loginable.rb
module Loginable
# Include default devise modules. Others available are:
# :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :omniauthable
def password_require?
new_record?
end
end
但服务器似乎不喜欢这样,因为它加载了NoMeethodError
loginable.rb:4:in `<module:Loginable>': undefined method `devise' for Loginable:Module (NoMethodError)
有没有办法做我正在拍摄的,或者不是真的?
由于
答案 0 :(得分:2)
这不是您正在寻找的答案,但是,这是我的2美分:您不应该将所有这些内容放在用户模型中。设计模型有明确的责任:签字。
但是如果你真的想把所有东西都挂在User.rb中,你可以将模型拆分为扩展(部分启用DCI):
将其添加到lib / models / {modelname} /devise_ext.rb
module Models
module User
module DeviseExt
extend ActiveSupport::Concern
included do
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :omniauthable
end
module ClassMethods
end
module InstanceMethods
def password_require?
new_record?
end
end #InstanceMethods
end
end
end
然后,您只需将其添加到模型中:
include Models::User::DeviseExt
在我们公司的应用程序中,我们实际上在模型中根本没有代码,我们将所有内容都放在扩展中。
答案 1 :(得分:1)
我还没有使用Devise,但试试这个:
module Loginable
def self.included(base)
base.send :devise, :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :omniauthable
end
def password_require?
new_record?
end
end
在您的模型中,包括而不是扩展:
class User < ActiveRecord::Base
include Loginable
end
答案 2 :(得分:1)
这是一个老问题,但这里的答案并没有帮助我使用Rails 4.2。
问题在于,当您在模块中定义实例方法并将其包含到用户模型中时,它们实际上会在该实例上定义。
但是他们不会在email_required?
方法中定义的设计中覆盖相同的方法(如devise
)。因此,当您在用户模型本身上定义email_required?
时,它可以正常工作,但在包含的模块中,他们不会覆盖设计方法。
但是使用Ruby 2,您可以使用prepend
执行此操作。像这样:
module User::AuthHelper
extend ActiveSupport::Concern
included do
prepend DeviseInstanceMethods
devise :database_authenticatable, :async, :registerable, :recoverable, :rememberable, :trackable, :validatable, :confirmable, \
:omniauthable, omniauth_providers: [:facebook, :instagram], authentication_keys: [:username]
end
module DeviseInstanceMethods
def email_changed?
false
end
def email_required?
false
end
end
end
现在DeviseInstanceMethods
中的所有方法都会覆盖设计方法。
我不知道这是否是最佳解决方案,但它对我有用。希望它有所帮助。