FriendlyID 控制器名称验证包含问题
FriendlyID Controller names validates inclusion issue
基本上我有一个应用程序(使用设计),用户只需要一个电子邮件和密码就可以注册 registrations#new
;这将注册并创建用户。它会立即将他们带到 registrations#edit
,在那里他们输入其余信息。
我将 :name
属性与 friendly_id 一起用于个性化网址。此属性有 3 个要求:
- 必须一次写入,写入后不可更改
- 它不能是任何控制器名称(否则会破坏应用程序)。
- 独一无二
#2
所以我在我的模型中添加了以下验证:
`
validates :name, :exclusion => { :in => %w(
admin cars registrations users
), :message => "Sorry \"%{value}\" is taken!"}`
#3
我加了
validates_uniqueness_of :name
#1
我在 registrations#edit 下的视图中有以下内容:
<% if @user.name.blank?%>
<br>
<h2>Choose your username</h2>
<%= f.input :name, :value => "Username" , required: true, autofocus: true, label:false, class: 'usernameinputc' %>
<br>
如果它不存在,这会有效地向用户隐藏它。我遇到的问题是,如果他们输入一个控制器名称作为他们的 :name
或已经使用的东西,它将给出一个设计错误,并将它们发回但该字段将被隐藏。如果我删除条件,那么它允许他们更改他们的 :name
即使它是有效的?我怎样才能使它仅在名称属性尚未保存时显示?
注意:我试过 if @user.name.persisted?
它给了我 nilClass 的无方法错误(我想是因为 :name
不存在。
更新
所以我尝试将其添加为虚拟属性,我已将字段 :username 添加到我允许的参数中作为虚拟属性。 getter 和 setter 方法有点麻烦。我试过这个:
def username
self.name if self.name.persisted?
end
我仍然遇到无方法错误。
使用虚拟属性来保存表单中的值。
attr_accessor :desired_name
提交表单后,将填写 User.desired_name
。然后对值执行验证。如果通过,则将虚拟属性复制到数据库字段属性中,保存并重定向。 (或复制值,验证,如果有错误,将 .name
设置回 null。)如果真实字段不为空,则隐藏表单。
您应该知道,仅隐藏表单几乎是一种安全风险。您应该在 #update
方法中验证 .name
不存在现有值,因为黑客可以创建他们自己的表单并提交该值以更改它。
虚拟属性教程如下:http://railscasts.com/episodes/16-virtual-attributes
如果你试试这个会怎么样?这将根据黑名单验证您的名字,但也会在发生这种情况时将 user.name 设置为空白。这样您的 erb 仍将正确呈现。
validate do |user|
if %w(admin cars registrations users).include?(user.name)
user.errors[:name] << "Sorry \"" + user.name + "\" is taken!"
user.name = ""
end
end
基本上我有一个应用程序(使用设计),用户只需要一个电子邮件和密码就可以注册 registrations#new
;这将注册并创建用户。它会立即将他们带到 registrations#edit
,在那里他们输入其余信息。
我将 :name
属性与 friendly_id 一起用于个性化网址。此属性有 3 个要求:
- 必须一次写入,写入后不可更改
- 它不能是任何控制器名称(否则会破坏应用程序)。
- 独一无二
#2 所以我在我的模型中添加了以下验证: `
validates :name, :exclusion => { :in => %w(
admin cars registrations users
), :message => "Sorry \"%{value}\" is taken!"}`
#3
我加了
validates_uniqueness_of :name
#1 我在 registrations#edit 下的视图中有以下内容:
<% if @user.name.blank?%>
<br>
<h2>Choose your username</h2>
<%= f.input :name, :value => "Username" , required: true, autofocus: true, label:false, class: 'usernameinputc' %>
<br>
如果它不存在,这会有效地向用户隐藏它。我遇到的问题是,如果他们输入一个控制器名称作为他们的 :name
或已经使用的东西,它将给出一个设计错误,并将它们发回但该字段将被隐藏。如果我删除条件,那么它允许他们更改他们的 :name
即使它是有效的?我怎样才能使它仅在名称属性尚未保存时显示?
注意:我试过 if @user.name.persisted?
它给了我 nilClass 的无方法错误(我想是因为 :name
不存在。
更新
所以我尝试将其添加为虚拟属性,我已将字段 :username 添加到我允许的参数中作为虚拟属性。 getter 和 setter 方法有点麻烦。我试过这个:
def username
self.name if self.name.persisted?
end
我仍然遇到无方法错误。
使用虚拟属性来保存表单中的值。
attr_accessor :desired_name
提交表单后,将填写 User.desired_name
。然后对值执行验证。如果通过,则将虚拟属性复制到数据库字段属性中,保存并重定向。 (或复制值,验证,如果有错误,将 .name
设置回 null。)如果真实字段不为空,则隐藏表单。
您应该知道,仅隐藏表单几乎是一种安全风险。您应该在 #update
方法中验证 .name
不存在现有值,因为黑客可以创建他们自己的表单并提交该值以更改它。
虚拟属性教程如下:http://railscasts.com/episodes/16-virtual-attributes
如果你试试这个会怎么样?这将根据黑名单验证您的名字,但也会在发生这种情况时将 user.name 设置为空白。这样您的 erb 仍将正确呈现。
validate do |user|
if %w(admin cars registrations users).include?(user.name)
user.errors[:name] << "Sorry \"" + user.name + "\" is taken!"
user.name = ""
end
end