开发者

Is it possible to load Devise in an external module?

开发者 https://www.devze.com 2023-03-20 00:02 出处:网络
I am using Devise in Rails 3, and have a User model in rails that is starting to get kinda crowded.. so I would like to put all of the login meethods inside of a module and include them from my model.

I am using Devise in Rails 3, and have a User model in rails that is starting to get kinda crowded.. so I would like to put all of the login meethods inside of a module and include them from my model. I'm trying something like:

app/model/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, :ph开发者_如何学JAVAone_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

and

lib/autoloads/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

but the server doesn't seem to like that, as it loads with a NoMeethodError

loginable.rb:4:in `<module:Loginable>': undefined method `devise' for Loginable:Module (NoMethodError)

Is there a way to do what I'm shooting for, or not really?

Thanks


This is not the answer you are looking for but, here is my 2 cents: You shouldn't put all that stuff in the User model. devise models have a clear responsibility: signing.

But if you really want to put everything hooked in User.rb, you can split the model in extensions (partially enabling DCI):

Add that to your 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

Then, you just add it into your model:

include Models::User::DeviseExt

In the app we have in my company we actually have no code at all in models, we put everything in extensions.


I've not used Devise yet, but try this:

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

and in your model, include rather than extend:

class User < ActiveRecord::Base
  include Loginable
end


This is an old question, but answers here didn't help me with Rails 4.2.

The problem is that when you define instance methods inside a module and include it into User model, they actually get defined on that instance.

But they don't override same methods in devise itself (like email_required?) defined inside devise method. So when you define email_required? on User model itself it works fine, but in included module they don't override devise's method.

But with Ruby 2 you can do this with prepend. Like this:

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

Now all methods in DeviseInstanceMethods will override devise's methods. I don't know whether this is best solution, but it works for me. Hope it helps.

0

精彩评论

暂无评论...
验证码 换一张
取 消