轨道4中未定义的模型方法

时间:2015-10-16 08:15:00

标签: ruby-on-rails ruby

我正在尝试配置Google OAuth,我面临一个我无法解决的非常愚蠢的错误: 当我点击主页上的登录按钮时:

<% if user_signed_in? %>
  Signed in as <%= current_user.name %>. Not you?
  <%= link_to "Sign out", destroy_user_session_path,:method => :delete %>
<% else %>
  <%= link_to "Sign in with Google", user_omniauth_authorize_path(:google_oauth2) %>
<% end %>

对于#

,我得到此错误未定义方法find_for_google_oauth2

它说问题出在那条线上: @user = user.find_for_google_oauth2(request.env["omniauth.auth"], current_user)

这是我的app/controllers/users/omniauth_callbacks_controller.rb

&#13;
&#13;
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController

  def facebook
    # You need to implement the method below in your model (e.g. app/models/user.rb)
    @user = User.from_omniauth(request.env["omniauth.auth"])
    if @user.persisted?
      sign_in_and_redirect @user, :event => :authentication #this will throw if @user is not activated
      set_flash_message(:notice, :success, :kind => "Facebook") if is_navigational_format?
    else
      session["devise.facebook_data"] = request.env["omniauth.auth"]
      redirect_to new_user_registration_url
    end
  end

  def google_oauth2
    @user = User.find_for_google_oauth2(request.env["omniauth.auth"], current_user)
    if @user.persisted?
      flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Google"
      sign_in_and_redirect @user, :event => :authentication
    else
      session["devise.google_data"] = request.env["omniauth.auth"]
      redirect_to new_user_registration_url
    end
  end
end
&#13;
&#13;
&#13;

这是我的app / models / user.rb:

&#13;
&#13;
class User < ActiveRecord::Base
  before_save :default_values
  attr_accessor :delete_photo
  validates :first_name, presence: true
  validates :last_name, presence: true
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable, :omniauthable, :omniauth_providers => [:facebook,:google_oauth2]
  has_many :usertoskills
  has_many :skills, through: :usertoskills
  has_many :usertoprojects
  has_many :projects, through: :usertoprojects
  has_many :demands
  has_many :news
  has_attached_file :photo, :styles => { :small => "150x150>", :regular => "300x300>" },
                  :url  => "/assets/users/:id/:style/:basename.:extension",
                  :path => ":rails_root/public/assets/users/:id/:style/:basename.:extension",
                  :default_url => "/assets/users/default/:style/default.jpg"
  validates_attachment_content_type :photo, :content_type => ['image/jpeg', 'image/png']
  #def name
  #  "#{self.first_name.camelize} #{self.last_name.camelize}"
  #end
  def default_values
    if self.first_name && self.last_name
      self.name = "#{self.first_name.camelize} #{self.last_name.camelize}"
    end
  end

  def admin
    self.role == 'admin'
  end

  def accessible_demands
    if self.role == 'admin'
      @demands = Demand.all
    else
      @demands = []
      self.projects.each do |p| @demands.concat(p.demands) end
      @demands = Demand.includes(:project).where(projects: { collective: true }, demands: {user_id: self.id}) | @demands
    end
    return @demands
  end

  def accessible_projects
    if self.role == 'admin'
      @projects = Project.all
    else
      @projects = self.projects
    end
    return @projects
  end

  def accessible_transactions
    if self.role == 'admin'
      @transactions = Transaction.all
    else
      @transactions = Transaction.where(sender_id: self.id)
    end
  end

  def self.from_omniauth(auth)
  where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
    user.email = auth.info.email
    user.password = Devise.friendly_token[0,20]
    #user.first_name = auth.info.first_name
    #user.last_name = auth.info.last_name   # assuming the user model has a name
    #user.image = auth.info.image # assuming the user model has an image
  end

  def self.find_for_google_oauth2(access_token, signed_in_resource=nil)
    data = access_token.info
    user = User.where(:provider => access_token.provider, :uid => access_token.uid ).first
    if user
      return user
    else
      registered_user = User.where(:email => access_token.info.email).first
      if registered_user
        return registered_user
      else
        user = User.create(name: data["name"],
          provider:access_token.provider,
          email: data["email"],
          uid: access_token.uid ,
          password: Devise.friendly_token[0,20],
        )
      end
   end
 end
end

end
&#13;
&#13;
&#13;

提前感谢您的帮助!

1 个答案:

答案 0 :(得分:4)

您的班级中有defend次电话不匹配 - 您在end方法后错过了def self.from_omniauth(auth)。下一行的where错误地缩进,隐藏它。实际上,您的find_for_google_oauth2方法正在 中定义<{1}}方法。

这是Ruby社区惯例对双空缩进策略非常严格的原因之一。