我是Rails和Ruby的新手。我目前正在一个个人项目中,在允许用户注册之前,我必须检查该用户是否至少13岁。为此,我使用了一种自定义验证方法,称为check_age_is_above_13
。我遇到的问题是date_select
视图中的助手将日期分为dob(1i)
,dob(2i)
和dob(3i)
,并且我无法弄清楚如何在User
模型中访问这些日期。我的代码如下:
移民:
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :email, null: false
t.string :encrypted_password, null: false
t.string :first_name
t.string :last_name
t.string :gender
t.datetime :dob #date of birth
t.timestamps
end
end
end
该User
模型如下所示。我下面的代码片段发现在这里,尽管我必须承认这是一个有点..... OUT-日期:
class User < ActiveRecord::Base
#using Devise for Auth
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable, :trackable,
:confirmable
validates :gender, inclusion: { in: %w(female male unknown) }
validate :check_age_is_above_13
def check_age_is_above_13
#The following raises "undefined local variable or method `params'" exception
dob = Date.new params[:user]['dob(1i)'].to_i, params[:user]['dob(2i)'].to_i, params[:user]['dob(3i)'].to_i
#Trying the below code raises a "TypeError, expected numeric" exception,
#which is understandable, as "dob" does not exist in the params list
if ((Date.today - dob) / 365.25).to_i < 13
errors.add(:dob, "You must be at least 13 years old to register with us")
end
end
end
张贴注册表格时的参数如下所示:
{"utf8"=>"✓",
"authenticity_token"=>"49w4ylxRIDyuRTDASW+vsuFL6Q3eeWcyokKrNXt9taM=",
"user"=>{"email"=>"[email protected]",
"password"=>"[FILTERED]",
"password_confirmation"=>"[FILTERED]",
"first_name"=>"Benny",
"last_name"=>"Lava",
"gender"=>"male",
"location_id"=>"1",
"dob(1i)"=>"2001",
"dob(2i)"=>"8",
"dob(3i)"=>"27"},
"commit"=>"Sign up"}
dob(Xi)
在模型上Date
执行自定义验证之前,如何访问模型中的参数,以便可以先将其转换为对象?我正在使用Devise进行用户身份验证和注册,如果有什么不同的话。
编辑:和视图看起来像这样:
<h2>Sign Up</h2>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div>
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true %>
</div>
<div>
<%= f.label :password %><br />
<%= f.password_field :password, autocomplete: "off" %>
</div>
<div>
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "off" %>
</div>
<div>
<%= f.label :first_name %><br/>
<%= f.text_field :first_name %>
</div>
<div>
<%= f.label :last_name %><br/>
<%= f.text_field :last_name %>
</div>
<div>
<%= f.label :gender %><br/>
<%= f.select :gender, options_for_select(%w[female male -]) %>
</div>
<div>
<%= f.label :location_id %><br/>
<%= f.select :location_id, options_for_select(Location.all.collect { |l| [l.name, l.id]}), {:include_blank => false} %>
</div>
<div>
<%= f.label :dob, "Date of Birth" %><br/>
<%= f.date_select :dob, {include_blank: false, start_year: Date.today.year - 100, end_year: Date.today.year - 13, default: {day: 31, month: 1, year: 1991}} %>
</div>
<div><%= f.submit "Sign up" %></div>
<% end %>
<%= render "devise/shared/links" %>
您可以params
从控制器访问哈希并查看层,但不能从模型层访问。因此,尝试Date
在User
模型中创建对象为时已晚。严格来说,您应该已经dob
在控制器阶段填写了一个日期,但是如果没有,我建议您在验证之前重写一个create
设计控制器的方法并在dob
那里手动设置变量user
。只是为了澄清起见,省略了设计的主要部分,您需要这样的内容:
class Users::RegistrationsController < Devise::RegistrationsController
# POST /resource/sign_up
def create
build_resource
resource.dob = Date.new params[:user]['dob(1i)'].to_i, params[:user]['dob(2i)'].to_i, params[:user]['dob(3i)'].to_i
if resource.save
set_flash_message :notice, :signed_up
sign_in_and_redirect(resource_name, resource)
else
clean_up_passwords(resource)
render_with_scope :new
end
end
end
完成之后,您应该已经dob
从User
模型验证方法中删除了分配行dob
。
如果您不知道从哪里开始,请查看此要点,其中包含有关覆盖devise控制器的提示。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句