0
votes

I have a Community model which has_many :users, and Users model which belongs_to :community.

I need when a user signs up can create a Community in the same process and be assigned to this Community when sign up. If no community is created the user should not be created.

How should I do it? Perhaps creating a custom devise controller for user... Any idea would be appreciated.

Thanks


After changes of first response:

app/controllers/devise/registrations_controller.rb

 # GET /resource/sign_up
    def new
      logger.info "1"
      build_resource({})
      render_with_scope :new
    end

# POST /resource
def create
  logger.info "2"
  build_resource

  if Community.save_both_a_new_user_and_a_new_instance(resource)
    if resource.active_for_authentication?
      set_flash_message :notice, :signed_up if is_navigational_format?
      sign_in(resource_name, resource)
      respond_with resource, :location => redirect_location(resource_name, resource)
    else
      set_flash_message :notice, :inactive_signed_up, :reason => resource.inactive_message.to_s if is_navigational_format?
      expire_session_data_after_sign_in!
      respond_with resource, :location => after_inactive_sign_up_path_for(resource)
    end
  else
    clean_up_passwords(resource)
    respond_with_navigational(resource) { render_with_scope :new }
  end
end

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

<h2>Sign up</h2>

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

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

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

  <div><%= f.label :password_confirmation %><br />
  <%= f.password_field :password_confirmation %></div>
</br>
<h4>Introduce la contraseƱa de tu comunidad</h4>
<div><%= f.number_field :community_id %></div>
<p>o Crea una nueva comunidad</p>

</br>
<div><%= f.submit "Sign up" %></div>
<% end %>

<%= render "links" %>

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

<h2>Edit <%= resource_name.to_s.humanize %></h2>

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

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

  <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 %>

<h3>Cancel my account</h3>

<p>Unhappy? <%= link_to "Cancel my account", registration_path(resource_name), :confirm => "Are you sure?", :method => :delete %>.</p>

<%= link_to "Back", :back %>

GEMFILE:

source 'https://rubygems.org'
gem 'rails', '3.2.2'
gem 'sqlite3'
gem 'json'
gem 'execjs'
gem 'therubyracer'
gem 'devise'
gem "cancan"
gem 'paperclip'
gem "aws-s3"
gem 'pg'
gem 'twitter-bootstrap-rails'

group :assets do
  gem 'sass-rails',   '~> 3.2.3'
  gem 'coffee-rails', '~> 3.2.1'
  gem 'uglifier', '>= 1.0.3'
end

gem 'jquery-rails'
2
The logger info is not showed - Daniel

2 Answers

0
votes

Yes, sure, I think you have to customize your Devise Controller.

step1. create your local Devise controller file ( by running its own generator rake task or by manually copying its controller to your local folder), after that, your folder structure should look like:

app/controllers/devise/registrations_controller.rb
app/views/devise/registrations/new.html.erb
app/views/devise/registrations/edit.html.erb

step2. edit your app/controllers/devise/registrations_controller.rb:

# POST /resource
def create
  build_resource
  if resource.save   # change this line of code. 
    if resource.active_for_authentication?
      redirect_to root_path, :notice => "successfully registered..."
    else
      # other code ....
    end 
  else
    clean_up_passwords resource
    respond_with resource
  end 
end 

change the file above,

if resource.save   # change this line of code. 

to :

if Community.save_both_a_new_user_and_a_new_instance(resource)

Step3. implement the method in Community using transaction:

class Community
  def Self.save_both_a_new_user_and_a_new_instance(user)
     Community.transaction do 
       community = Community.new(:name => "new community")
       user.community = community
       community.save!
       user.save!
     end 
  end
end
0
votes

I re-do it all again and works!! The only things I had to change from your code were:

  • inherit Community from ActiveRecord (for using has_many) and
  • change self class method Self.save_both_a_new_user_and_a_new_instance(user) to self.save_both_a_new_user_and_a_new_instance(user).

Thanks!!