我昨天问了这个问题,但是在我解决了几个小时的问题之后,我才知道,我昨天问过的问题不是我遇到的问题。所以,我决定再问一次。
用户模型:
EMAIL_REGEX = /\A^[A-Za-z0-9](([_\.\-]?[a-zA-Z0-9]+)*)@([A-Za-z0-9]+)(([\.\-]?[a-zA-Z0-9]+)*)\.([A-Za-z]{2,})$\z/
# Matches -> he_llo@worl.d.com hel.l-o@wor-ld.museum h1ello@123.com
# Non-Matches -> hello@worl_d.com he&llo@world.co1 .hello@wor#.co.uk
# http://regexlib.com/REDetails.aspx?regexp_id=333
ALL_LETTERS_AND_SINGLE_SPACES = /\A^([a-zA-Z]+\s?)*$\z/
ALL_LETTERS_AND_NUMBERS = /\A^[a-zA-Z0-9]+$\z/
WEBSITE = /\A(www.)?([a-zA-Z0-9]+).[a-zA-Z0-9]*.[a-z]{3}.?([a-z]+)?\z/
# First Name
validates :first_name,
presence: {message: 'First name cannot be blank'},
length: {maximum: 50, message: 'First name cannot be longer than 50 characters'},
format: {with: ALL_LETTERS_AND_SINGLE_SPACES, message: 'First name should contain only letters and single space'}
# Last Name
validates :last_name,
presence: {message: 'Last name cannot be blank'},
length: {maximum: 50, message: 'Last name cannot be longer than 50 characters'},
format: {with: ALL_LETTERS_AND_SINGLE_SPACES, message: 'Last name should contain only letters and single space'}
# Email
validates :email,
presence: {message: 'Email cannot be blank'},
length: {maximum: 100, message: 'Email cannot be longer than 100 characters'},
format: {with: EMAIL_REGEX, message: 'Email is not valid'},
uniqueness: {case_sensitive: false, message: 'This email is already registered'},
confirmation: {message: 'Email address does not match'}
# Password
validates :password_digest,
presence: {message: 'Password cannot be blank'},
length: {minimum: 8, message: 'Password length should be minimum 8 characters'}
# Username
validates :username,
presence: {message: 'Username cannot be blank'},
length: {minimum: 3, message: 'Email cannot be shorter than 3 characters'},
format: {with: ALL_LETTERS_AND_NUMBERS, message: 'Username should contain only letters and numbers'},
uniqueness: {case_sensitive: false, message: 'This username is already in use'}
# Website
validates :website,
format: {with: WEBSITE, message: 'Invalid email format. Make sure you don\'t have http:// in your link'}
# Information
validates :information,
length: {maximum: 100, message: 'Information cannot be longer than 99 characters'}
如您所见,我对数据库中的某些列进行了验证。我需要的是在用户注册时验证first_name,last_name,电子邮件和密码,并在用户编辑他/她的配置文件设置时验证first_name,last_name以及网站,信息,用户名。
但是,rails会自动验证您注册页面中是否包含用户名字段的所有列。它只是验证了一切。但我不希望rails在注册时验证用户名或网站。
配置文件控制器:
def update
# Find an existing object using form parameters
@profile = User.find_by_id(current_user.id)
# Update the object
if @profile.update_attributes!(settings_profile_params)
# If save succeeds, redirect to itself
redirect_to request.referrer
else
# If save fails, redisplay the form so user can fix the problems
render('edit')
end
end
private # user_params is not an action, that is why it is private.
def settings_profile_params
params.require(:user).permit(:first_name, :last_name, :username, :school, :program, :website, :information)
end
用户控制器:
def create
# Instantiate a new object using form parameters
@user = User.new(user_params)
# Save the object
if @user.save
# If save succeeds, redirect to the dashboard action
cookies[:authorization_token] = @user.authorization_token
redirect_to dashboard_path
else
# If save fails, redisplay the form so user can fix the problems
render('new')
end
end
private # user_params is not an action, that is why it is private.
def user_params
params.require(:user).permit(:first_name, :last_name, :email, :email_confirmation, :password)
end
我认为rails会验证仅在强参数中传递的那些,但事实并非如此。我相信它应该很容易解决,但我不能。
谢谢。
答案 0 :(得分:1)
我不知道这样做的惯用方法。对于您希望仅在更新时运行的个人验证,您可以执行
validates :username,
...
on: :update # or on: :create
或者,如果您希望它们仅在表单中提供属性时运行,
validates :username,
...
if: :username_changed?
对于更激进的解决方案,您可能需要考虑将模型分解为两个 - 一个包含在注册(User
)上创建的属性,另一个包含其余属性(a {{1或UserDetails
)UserProfile
。此时,在工作流程的不同阶段使用不同的验证逻辑变得简单。
答案 1 :(得分:0)
模型中的验证大部分时间都是关于表单的。
Ryan Bates已经发布了an excellent RailsCast关于如何重构模型的方法,其方式是为每个表单使用不同的对象。
这样,您可以组合模型和/或定义不同的行为和/或验证,具体取决于提交数据的表单。
这样做的方式很难描述,所以在这里发布代码会很混乱。
我强烈建议您访问上述链接,您将在那里得到答案。
答案 2 :(得分:-1)
您可以使用:if option:
class Order < ActiveRecord::Base
validates :card_number, presence: true, if: :paid_with_card?
def paid_with_card?
payment_type == "card"
end
end
但我认为你正在寻找allow_nil或allow_blank选项:
3.1:allow_nil
:allow_nil选项在值为时跳过验证 验证是零。
class Coffee < ActiveRecord::Base
validates :size, inclusion: { in: %w(small medium large),
message: "%{value} is not a valid size" }, allow_nil: true
end
3.2:allow_blank
:allow_blank选项类似于:allow_nil选项。这个 如果属性的值为空,会选择验证吗? 比如nil或空字符串。
class Topic < ActiveRecord::Base
validates :title, length: { is: 5 }, allow_blank: true
end
Topic.create(title: "").valid? # => true
Topic.create(title: nil).valid? # => true