FriendlyID控制器名称验证包含问题

时间:2015-08-10 04:05:46

标签: ruby-on-rails ruby devise friendly-id write-once

基本上我有一个应用程序(使用设计),用户只需一封电子邮件和密码即可注册registrations#new;这会注册并创建用户。它立即将它们带到registrations#edit,在那里他们输入其余的信息。

我使用带有friendly_id的:name属性作为虚荣网址。该属性有3个要求:

  1. 必须写一次,但写完后不可更改。
  2. 它不能是任何控制器名称(或者它会破坏应用程序)。
  3. 很独特
  4. #2 所以我在我的模型中添加了以下验证: `

      validates :name, :exclusion => { :in => %w(
      admin cars registrations users
     ), :message => "Sorry \"%{value}\" is taken!"}`
    

    #3 我补充道 validates_uniqueness_of :name

    #1 我在注册#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?我怎样才能使它只显示name属性没有保存?

    注意:我尝试if @user.name.persisted?它为nilClass提供了一个no方法错误(我认为因为:name不存在。

    更新

    所以我尝试将其添加为虚拟属性,我在我允许的参数中添加了一个字段:用户名作为虚拟属性。使用getter和setter方法遇到一些麻烦。我试过这个:

    def username
      self.name if  self.name.persisted?
    end
    

    我仍然没有方法错误。

2 个答案:

答案 0 :(得分:1)

如果你试试这个怎么办?这将根据黑名单验证您的名称,但在发生这种情况时也会将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

答案 1 :(得分:-2)

使用虚拟属性保存表单中的值。

attr_accessor :desired_name

提交表单后,将填写User.desired_name。然后对该值执行验证。如果它通过,则将虚拟属性复制到数据库字段属性并保存并重定向。 (或者复制值,验证,如果有错误,请将.name设置为null。)如果实际字段不为空,则隐藏表单。

您应该知道,仅隐藏表单几乎是一种安全风险。您应该在#update方法中验证.name尚未存在现有值,因为黑客可以创建自己的表单并提交值以进行更改。

以下是虚拟属性的教程:http://railscasts.com/episodes/16-virtual-attributes