这是我当前的用户流程:
在主页上输入电子邮件 ==>如果电子邮件有效,则创建新的注册记录,并将用户重定向到步骤2;如果电子邮件无效,则不会创建新的注册记录,并且会重新呈现主页以供用户重新提交电子邮件
在编辑注册页面输入其余的注册信息(让我们只说zipcode)==>如果邮政编码有效,则注册记录会更新,用户会进入网站的其余部分,否则,此编辑注册页面将重新呈现,并显示错误,以便用户重新提交邮政编码
对于相同的注册,有两个单独的验证,一次在主页上以确保电子邮件有效,一旦在更新操作的编辑页面上,以确保邮政编码有效。
(为什么这个麻烦的两步呢?用户可能会因为在第2步输入他们的信息而过于恐吓,但我至少想通过他们的邮件列表中的电子邮件来吸引他们的兴趣,以便将来联系。)< / p>
我遇到了非常恼人的问题,由这些流程代表:
示例1
示例2
似乎邮政编码验证在创建步骤中以某种方式触发,但我真的不明白为什么......我在关于参数的控制器代码的评论中有一个理论,但是我没有理论没有答案。
帮助表示赞赏!
型号代码
class Signup
validate :create_validation, on: :create
validate :update_validation, on: :update
def create_validation
errors[:base] << "Please enter a valid email address to continue" if self.email.blank? || (( /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i =~ self.email) == nil)
end
def update_validation
errors[:base] << "Please enter a valid 5-digit zipcode so we can find items closer to you" if self.zipcode.blank? || (self.zipcode < 0) || (self.zipcode.to_s.strip.length != 5)
end
end
路线代码
root 'signups#new' #normal code
resources :signups, only: [:new, :create]
get '/edit', to: 'signups#edit', as: 'edit_signup'
patch 'signups/update', to: 'signups#update'
控制器代码
class SignupsController < ApplicationController
def new
@signup = Signup.new
end
def create
@signup = Signup.new
email = signup_params["email"]
if Signup.where(email: email.downcase).exists?
session[:signup_email] = email.downcase
redirect_to action: 'edit'
else
@signup = Signup.create(signup_params)
# I wonder if signup_params the problem since it also has zipcode? If so how do I change it? I tried writing Signup.create(email), or Signup.create(signup_params["email"]) or Signup.create(signup_params[:email]) and kept getting the error: When assigning attributes, you must pass a hash as an argument
if @signup.save
Subscribe.new.async.perform(@signup)
Mailing.new.async.perform(@signup)
session[:signup_email] = @signup.email
redirect_to action: 'edit'
else
render new_signup_path
end
end
end
def edit
if session[:signup_email].nil?
flash[:danger] = "Please enter your email to get started"
redirect_to root_path
else
@signup_parent = Signup.find_by_email(session[:signup_email])
end
end
def update
@signup_parent = Signup.find_by_email(session[:signup_email])
if @signup_parent.update_attributes(signup_params)
redirect_to success_path
else
render "edit"
end
end
def signup_params
params.require(:signup).permit(:email, :zipcode)
end
end
答案 0 :(得分:0)
神圣的废话我解决了这个问题!在Signups控制器中,这两行正在弄乱它
@signup = Signup.create(signup_params)
if @signup.save
...
create
已包含save
,因此当第二个save
被调用时,这就是更新验证开始的原因。新代码:
@signup = Signup.new(signup_params)
if @signup.save
...
我还有两个有趣的观点:
/edit
页面,因为验证问题应该再次启动if @signup.create(signup_params)
无效,因为它在语法上与new
+ save
相同。发生的情况是,如果用户输入的字符串不是有效的电子邮件,例如&#34; asfd&#34;,即使没有edit
记录,也会触发Signup
页面已被记录(意味着由于@signup_parent
不存在而发生错误)