2011-07-14 5 views
1

私はDevise in Rails 3を使用しており、レールにUserモデルを持っていて、ちょっと混雑しています。私はモジュールの中にすべてのログインメソッドを入れて、それらをモデルから取り込みたいと思います。私のような何かをしようとしている:Deviseを外部モジュールにロードすることは可能ですか?

アプリ/モデル/ 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) 

私が撮影しているものを行う方法はありますか、それとも本当ですか?

おかげ

答えて

2

は、これは私の2セントで、ここで、あなたが探している答えではないですが:あなたはUserモデルにすべてのものを置くべきではありません。モデルには明確な責任があります。

しかし、あなたが本当にUser.rbに夢中にすべてをかけるしたい場合は、(部分的にDCIを有効にする)の拡張機能でモデルを分割することができます。

あなたのlib /モデル/ {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 

、我々は拡張子にすべてをかけます。

+0

こんにちは、私はこれでかなり新しいので、コードを整理する上であなたが提供しなければならないアドバイスや専門知識がありがとうと思います。あなたは私があなたがレイアウトした設定に行くことを提案しました。あるいは、「私はUserモデルにそのすべてを入れてはいけません」と言いましたが、別の方法がありますか?ありがとうございました! – noli

+0

私も同様の機能を多くのモジュールにグループ分けする方向に向かっています。私のモデルはますます激しくなってきています。あなたはどこでも入手可能なこのスタイルの書き込みを持っていますか? – noli

+1

Eduardoの答えと私の大きな違いは、私がRubyの最小限のソリューションであることです.Eduardo'sはRails固有のActiveSupport :: Concernモジュールを使用しています。これは一般的なモジュールのリファクタリングを規定しています。 – gtd

1

私はまだ工夫を使用し、これを試していませんでした:

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 
1

これは古い質問ですが、ここでは答えはdidnのRails 4.2を手伝ってください。

問題は、インスタンスメソッドをモジュール内で定義し、それをUserモデルに含めると、実際にそのインスタンスに定義されるということです。

しかし、deviseメソッドの中に定義されたデバイス自体(email_required?など)の同じメソッドをオーバーライドしません。したがって、ユーザモデル自体にemail_required?を定義すると、うまく動作しますが、含まれているモジュールでは、deviseのメソッドをオーバーライドしません。

しかし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のすべてのメソッドは、工夫のメソッドをオーバーライドします:このように。 これが最善の解決策であるかどうかわかりませんが、それは私にとってはうまくいきます。それが役に立てば幸い。

関連する問題