Jump to content

The ultimate community for Ruby on Rails developers.


Photo

Devise with nested form


  • Please log in to reply
1 reply to this topic

#1 Jamie

Jamie

    Controller

  • Moderators
  • 114 posts
  • LocationThe UK

Posted 15 September 2013 - 09:54 AM

Hi guys

 

I'm really bashing my head against a wall here with this but I've tried a few different ways I found through Google searches but I can't seem to get one that works.

 

I'm using Devise and on the sign_up form I want to include a nested form for a relation called 'Site'.

 

Users can have multiple Sites. Site belongs to one User.

 

When the form submits it only creates the user and ignores the Site.

 

I'm using Simple_Form and here are the files:

 

ApplicationController.rb

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception

  # Devise Parameters
  before_filter :configure_permitted_parameters, if: :devise_controller?

  protected

  # Devise Parameters
  def configure_permitted_parameters
    devise_parameter_sanitizer.for(:sign_up) << [:first_name, :last_name, :phone_no, sites_attributes: [:name, :subdomain, :user_id]]
  end

end

models/user.rb

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  has_many :sites
  accepts_nested_attributes_for :sites
end

models/site.rb

class Site < ActiveRecord::Base
	belongs_to :user
end

views/devise/registrations/new.html.erb

<h2>Sign up</h2>

<% resource.sites.build %>

<%= simple_form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>

	<%= f.error_notification %>

	<fieldset>
		<legend>Account Info</legend>

		<%= f.input :first_name, :required => true, :autofocus => true %>
		<%= f.input :last_name, :required => true %>
		<%= f.input :phone_no, :required => true %>

		<%= f.input :email, :required => true %>

		<%= f.input :password, :required => true %>
		<%= f.input :password_confirmation, :required => true %>
	</fieldset>

	<fieldset>
		<legend>Site Details</legend>

		<%= f.simple_fields_for :site do |s| %>

			<%= s.input :name %>
			<%= s.input :subdomain %>

		<% end %>

	</fieldset>

	<%= f.button :submit, "Sign up" %>

<% end %>

<%= render "devise/shared/links" %>

Any help would be appreciated.

 

I know placing 

<% resource.sites.build %>

in the View is a bit ugly, and I'll happily move it into a controller if someone can just lend a hand getting the whole thing working.

 

I would assume I'll need to recreate the new method and override the default Devise registration#new method but I just cannot for the life of me, get this to work anyway I've tried.

 

I thought my example above would work regardless of overriding the Devise controller.

 

 

Thanks in advance guys :)


Rails developer based in Newcastle, UK.
Web app owner - Twitter lover

#2 quentinuys

quentinuys

    Passenger

  • Members
  • 1 posts

Posted 11 April 2014 - 07:02 AM

I don't know if you have solved this question already but I thought I will post my solution just in case anybody else have the same issue.

 

The solution is actually pretty simple if you think about it. 

 

In you Site ActiveRecord place the following

def site
  super || build_site
end

If site is empty when requested it will build it.

 

Hope it helps






0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users