1
votes

I am trying to include nested attributes inside my Devise edit.html.erb file.

My models:

class User < ActiveRecord::Base
  has_one :tutor, dependent: :destroy
  accepts_nested_attributes_for :tutor, allow_destroy: true

  devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable

end

and

class Tutor < ActiveRecord::Base
  belongs_to :user
end

in my ApplicationController:

class ApplicationController < ActionController::Base
  before_filter :configure_permitted_parameters, if: :devise_controller?
  protect_from_forgery with: :exception

  protected
    def configure_permitted_parameters
      devise_parameter_sanitizer.for(:account_update) do |u|
        u.permit(:first_name, :last_name, :email,
        :is_tutor, :password,
        # This is important for nested attributes
        tutor_attributes: [:id, :_destroy, :user_id, :description] 
        :password_confirmation, :current_password)
      end
    end
end

And my view:

<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :multipart => true }) do |f| %>
  <%= devise_error_messages! %>

  <div><%= f.label :email %><br />
  <%= f.email_field :email, :autofocus => true %></div>

  <% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
    <div>Currently waiting confirmation for: <%= resource.unconfirmed_email %></div>
  <% end %>

  <div><%= f.label :first_name %><br />
  <%= f.text_field :first_name %></div>

  <div><%= f.label :last_name %><br />
  <%= f.text_field :last_name %></div>

  <p>
    <%= f.check_box :is_tutor %>
    <%= f.label :is_tutor, 'Tutor' %>
  </p>

    <div>
        <%= f.fields_for :tutor do |builder| %>
        <fieldset>
            <%= builder.label :description, 'Description' %><br />
            <%= builder.text_area :description %><br />
            <%= builder.check_box :_destroy %>
            <%= builder.check_box :_destroy, 'Remove description' %>
        </fieldset>
        <% end %>
    </div>

    <br />
  <div><%= f.label :password %> <i>(leave blank if you don't want to change it)</i><br />
  <%= f.password_field :password, :autocomplete => "off" %></div>

  <div><%= f.label :password_confirmation %><br />
  <%= f.password_field :password_confirmation %></div>

  <div><%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
  <%= f.password_field :current_password %></div>

  <div><%= f.submit "Update" %></div>
<% end %>

When I go to the edit page, I do not see the fieldset with the nested attributes. The query to the db looks like this:

User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 ORDER BY "users"."id" A SC LIMIT 1

Tutor Load (3.2ms) SELECT "tutors".* FROM "tutors" WHERE "tutors"."user_id" = ? ORDER BY "tuto rs"."id" ASC LIMIT 1 [["user_id", 1]]

Any idea what I might be doing wrong?

Thanks!

1
What's resource set to? Is it a new user?lurker
That's Devise's default setting. It's the form for the current user session I imagine, but I'm not entirely sure.DaniG2k

1 Answers

2
votes

This is probably due to the fact there is not a tutor association connected to the user. The fields would not show if the tutor was nil.

If so, you'll need to figure out how to do this on the user.

@user.build_tutor

Some options for adding this - You may need to overwrite the devise controller/method to add this. There may be some hooks provided by devise. You may do this in the view.