【问题标题】:Simple_form hidden field breaks Devise validation in rails 3.2 appSimple_form 隐藏字段破坏 Rails 3.2 应用程序中的设计验证
【发布时间】:2013-06-22 18:53:32
【问题描述】:

我正在使用设计进行身份验证,并让用户与建筑物相关联。我可以创建与正确建筑物适当关联的新用户,但如果新用户没有所有必需的输入,我会设计验证中断。

代码:

app/models/user.rb

class User < ActiveRecord::Base
  belongs_to :building
  attr_accessible :building_id
  ...
end

(我知道拥有 building_id attr_accessible 并不理想,但我不确定如何在不使用新用户注册表单中的 building_id 隐藏字段的情况下创建关联...)

class Building < ActiveRecord::Base
  has_many :users
  ...
end

在我的路线中,用户注册嵌套在建筑物内:

devise_for :users, controllers: { :registrations => "registrations" }, skip: [:registrations]

resources :users, except: [:new, :create] do
  resource :approvals, only: [:update]
end

match '/:building', to: "buildings#landing"
resources :buildings, except: [:new, :create, :destroy] do
  as :user do
    get '/signup' => 'registrations#new', as: :new_user_registration
    post '/signup' => 'registrations#create', as: :user_registration
  end
  ...
end

app/views/devise/registrations/new.html.erb

<%= simple_form_for(resource, :as => resource_name, :url => building_user_registration_path(), :html => {:class => 'form-inline', :multipart => true }) do |f| %>

    <%= render 'fields', f: f %>

  <div class="inputs">
    <%= f.input :role, collection: User::ROLES.collect %>
    <%= f.input :password, :required => true %>
    <%= f.input :password_confirmation, :required => true %>
  </div>

  <div class="actions">
    <%= f.button :submit, "Create my account", class: "btn btn-large btn-primary" %>
  </div>
<% end %>

最后,app/views/devise/registrations/_fields.html.erb 中的那行代码

...
 <%= f.hidden_field :building_id, value: @building.id %>
...

如果正确填写了新用户的所有必填字段,则会创建一个与正确建筑物适当关联的新用户。如果任何必填字段为空白或无效,Devise 将在浏览器中引发以下错误:

RuntimeError in Registrations#create

Showing .../app/views/devise/registrations/_fields.html.erb where line #7 raised:

Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id

第 7 行是:&lt;%= f.hidden_field :building_id, value: @building.id %&gt;

任何想法将不胜感激。我确定我在这里做了几件次优的事情......

【问题讨论】:

  • 我不太明白你的意思。如果用户没有输入正确的消息,验证失败不是期望的结果吗?
  • 我听到了,@BillyChan。更清楚地说,“成功验证失败” ;-) 如果没有该行 #7 会重新呈现表单,其中包含“请更正以下问题:”之类的内容,并突出显示空白的必填字段。包含第 7 行且输入无效时,我会得到一个“动作控制器:异常捕获”错误页面,其中包含上述错误。
  • "Called Id for nil" 意味着 @building 是 nil。这个对象真的在控制器中设置并有效吗?
  • @BillyChan 这可能是我的问题之一。我正在使用 Devise,我不确定当 Devise 在验证失败后重新呈现新的用户注册页面时发生了什么以及如何更改它。提交失败前后的注册表单的url都是http://0.0.0.0:5000/buildings/[building.slug]/signup

标签: ruby-on-rails devise ruby-on-rails-3.2 simple-form


【解决方案1】:

你可以的

<%= f.hidden_field :building_id, value: @building.try(:id) %>

但如果没有@building 设置,我宁愿完全不包含此字段

【讨论】:

  • 感谢@MichaelSzyndel 的建议。您的代码不会生成错误,并允许重新呈现新的用户注册表单,并显示设计警告“请查看以下问题:”。但它不会填充 building_id 字段。不知何故,我必须设置@building。我刚试过&lt;%= f.hidden_field :building_id, value: Building.find(params[:building_id]) %&gt;,但也没有用。
  • 您对 User#building 进行了验证吗?
  • 感谢您的见解,@MichaelSzyndel。我确实对 user.building_id 进行了验证。它必须存在。我确实得到了这个工作 - 请参阅下面的答案。
【解决方案2】:

我在朋友的帮助下成功了。我已经有一个自定义注册控制器(在我的路线中提到),我添加了一个前置过滤器来查找建筑物:

class RegistrationsController < Devise::RegistrationsController

  before_filter :find_building, only: [:new, :create]

  ...

  private

  def find_building
    @building = Building.find_by_slug(params[:building_id])
  end

end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-24
    • 2012-12-06
    • 1970-01-01
    • 2012-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多