在 rails 中使用 attr_accessor 试图跳过验证
Using attr_accessor in rails trying to skip validations
我试图跳过密码验证,因为 facebook 没有 return 登录密码。
我收到一个错误;
"Validation failed: Password can't be blank" 在线 user.save!
应用程序跟踪;
app/models/user.rb:36:in block in 'from_omniauth'
app/models/user.rb:29:in 'from_omniauth'
app/controllers/sessions_controller.rb:6:in 'create'
这是因为 from_omniauth
是一个 class 方法,包装在用户变量中然后我试图跳过密码验证,作为实例变量,当实例尚未创建时.即first_or_create do |user|
没有在实例之前创建或注册用户?
如果是这样,我想知道如何重构我的代码以使其正常工作?
会话控制器
class SessionsController < ApplicationController
def create
user = User.from_omniauth(env["omniauth.auth"])
user.skip_password_validation = true
...
model.rb
class User < ApplicationRecord
has_secure_password
validates :password, presence: true, length: { minimum: 6 }, allow_nil: true,
unless: :skip_password_validation
attr_accessor :skip_password_validation
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
user.provider = auth.provider
user.uid = auth.uid
user.name = auth.info.name
user.email = auth.info.email
user.oauth_token = auth.credentials.token
user.oauth_expires_at = Time.at(auth.credentials.expires_at)
user.save!
end
end
end
您可以将 skip_password 参数传递给您的实例函数:
def self.from_omniauth(auth, skip_password)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
user.provider = auth.provider
user.uid = auth.uid
user.name = auth.info.name
user.email = auth.info.email
user.oauth_token = auth.credentials.token
user.oauth_expires_at = Time.at(auth.credentials.expires_at)
user.skip_password_validation = skip_password
user.save!
end
结束
然后这样称呼它:
user = User.from_omniauth(env["omniauth.auth"], true)
添加用户模型
attr_accessor :password
有了这个,问题是 has_secure_password
,这里默认显示了 3 种验证方法 api.rubyonrails。org/classes/ActiveModel/SecurePassword/ClassMethods。html。您在 has_secure_password validations: false
中添加,并且可以在 validates
方法中手动添加验证。正确的代码应该是,
会话控制器
class SessionsController < ApplicationController
def create
user = User.from_omniauth(env["omniauth.auth"])
...
型号
has_secure_password validations: false
validates :password, on: :create, presence: true, length: { minimum: 6 }, allow_nil: true,
unless: :skip_password_validation
attr_accessor :skip_password_validation
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
user.provider = auth.provider
user.uid = auth.uid
user.name = auth.info.name
user.email = auth.info.email
user.oauth_token = auth.credentials.token
user.oauth_expires_at = Time.at(auth.credentials.expires_at)
user.skip_password_validation = true
user.save!
end
...
EDIT 我再次回到这个问题,因为在另存为 rails 评估模型方法之前,您需要在模型对象的模型中使用 skip 方法第一的。因此,您可以按照@Vladan Markovic 所写的方式进行操作,或者在调用保存之前将 user.skip_password_validation = true
简单地放入模型中的 from_omniauth
方法中,我已对其进行编辑以显示。
我试图跳过密码验证,因为 facebook 没有 return 登录密码。
我收到一个错误;
"Validation failed: Password can't be blank" 在线 user.save!
应用程序跟踪;
app/models/user.rb:36:in block in 'from_omniauth'
app/models/user.rb:29:in 'from_omniauth'
app/controllers/sessions_controller.rb:6:in 'create'
这是因为 from_omniauth
是一个 class 方法,包装在用户变量中然后我试图跳过密码验证,作为实例变量,当实例尚未创建时.即first_or_create do |user|
没有在实例之前创建或注册用户?
如果是这样,我想知道如何重构我的代码以使其正常工作?
会话控制器
class SessionsController < ApplicationController
def create
user = User.from_omniauth(env["omniauth.auth"])
user.skip_password_validation = true
...
model.rb
class User < ApplicationRecord
has_secure_password
validates :password, presence: true, length: { minimum: 6 }, allow_nil: true,
unless: :skip_password_validation
attr_accessor :skip_password_validation
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
user.provider = auth.provider
user.uid = auth.uid
user.name = auth.info.name
user.email = auth.info.email
user.oauth_token = auth.credentials.token
user.oauth_expires_at = Time.at(auth.credentials.expires_at)
user.save!
end
end
end
您可以将 skip_password 参数传递给您的实例函数:
def self.from_omniauth(auth, skip_password)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
user.provider = auth.provider
user.uid = auth.uid
user.name = auth.info.name
user.email = auth.info.email
user.oauth_token = auth.credentials.token
user.oauth_expires_at = Time.at(auth.credentials.expires_at)
user.skip_password_validation = skip_password
user.save!
end
结束
然后这样称呼它:
user = User.from_omniauth(env["omniauth.auth"], true)
添加用户模型
attr_accessor :password
有了这个,问题是 has_secure_password
,这里默认显示了 3 种验证方法 api.rubyonrails。org/classes/ActiveModel/SecurePassword/ClassMethods。html。您在 has_secure_password validations: false
中添加,并且可以在 validates
方法中手动添加验证。正确的代码应该是,
会话控制器
class SessionsController < ApplicationController
def create
user = User.from_omniauth(env["omniauth.auth"])
...
型号
has_secure_password validations: false
validates :password, on: :create, presence: true, length: { minimum: 6 }, allow_nil: true,
unless: :skip_password_validation
attr_accessor :skip_password_validation
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
user.provider = auth.provider
user.uid = auth.uid
user.name = auth.info.name
user.email = auth.info.email
user.oauth_token = auth.credentials.token
user.oauth_expires_at = Time.at(auth.credentials.expires_at)
user.skip_password_validation = true
user.save!
end
...
EDIT 我再次回到这个问题,因为在另存为 rails 评估模型方法之前,您需要在模型对象的模型中使用 skip 方法第一的。因此,您可以按照@Vladan Markovic 所写的方式进行操作,或者在调用保存之前将 user.skip_password_validation = true
简单地放入模型中的 from_omniauth
方法中,我已对其进行编辑以显示。