Simple_form隐藏字段中断rails 3.2 app中的设计验证

时间:2013-06-22 18:53:32

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

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

代码:

应用程序/模型/ 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

应用程序/视图/设计/注册/ 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行是:<%= f.hidden_field :building_id, value: @building.id %>

任何想法都将不胜感激。我确信我在这里做了几件不理想的事情......

2 个答案:

答案 0 :(得分:3)

你可以做到

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

但如果没有@building设置

,我宁愿不要包含此字段

答案 1 :(得分:0)

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

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