I'm using devise in rails, and I'm trying to create a second registration path, the default registration path for users (which works perfectly), and a second registration path whereby a user registers and creates a project in a single action as a "Getting Started" action (Think Freelancer.com or any marketplace whereby non-users can register and create their first project in one action).
I've gone through so many threads but they all seem to want to replace the existing registration action. I want to keep the existing registration action and either add a getting_started_new and getting_started_create actions to the existing User::Registration controller, or create a new GettingStarted Controller with methods for new and create that would then allow the nested form (for a user and their new project).
My latest iteration looks something like this:
routes.rb
devise_for :users
resources :users do
resources :projects
end
devise_scope :user do
get "getting_started" =>'getting_started#new'
post "getting_started" =>'getting_started#create'
end
getting_started_controller.rb
class GettingStartedController < Devise::RegistrationsController
def new
#user = User.new
#user.projects.build
end
def create
#user = User.new(getting_started_params)
redirect_to root, notice: "Done"
end
private
def getting_started_params
params.require(:user).permit(:first_name, :last_name, :phone, :password, :email, projects_attributes: [:user_id, :project_type_id, :name, :industry_id, :description, :budget_id, :project_status_id, feature_ids:[], addon_ids:[]])
end
end
But when I try and actually submit the form, it loads the getaction from the new controller, and the post action from the devise registration controller.
Started GET "/getting_started" for ::1 at 2016-10-17 09:15:58 +0200
Processing by GettingStartedController#new as HTML
Rendering getting_started/new.html.erb within layouts/application
Project_type Load (0.5ms) SELECT "project_types".* FROM "project_types"
Industry Load (1.1ms) SELECT "industries".* FROM "industries" ORDER BY "industries"."name" ASC
Feature Load (0.5ms) SELECT "features".* FROM "features" ORDER BY "features"."name" ASC
Addon Load (0.4ms) SELECT "addons".* FROM "addons"
Budget Load (0.4ms) SELECT "budgets".* FROM "budgets"
Rendered getting_started/new.html.erb within layouts/application (32.9ms)
Rendered layouts/_header.html.erb (1.9ms)
Rendered layouts/_footer.html.erb (0.7ms)
Completed 200 OK in 97ms (Views: 86.4ms | ActiveRecord: 2.9ms)
Started POST "/users" for ::1 at 2016-10-17 09:16:54 +0200
Processing by Devise::RegistrationsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"hYrC/15zIF3DzPvhpFQH6LVS9H8XbhfHY1aRkgc2iX6Mdfvz33/O4p72XTpmY4X8E6B+dGfOmjZw7IoizvYwSA==", "user"=>{"first_name"=>"John", "last_name"=>"Smith", "phone"=>"0340239402309", "email"=>"test#example.com", "password"=>"[FILTERED]", "project"=>{"name"=>"This is a test", "description"=>"Tester Description", "feature_ids"=>[""], "addon_ids"=>[""]}}, "project"=>{"project_type_id"=>"4", "industry_id"=>"2", "budget_id"=>"1"}, "commit"=>"Create account"}
Unpermitted parameter: project
(0.1ms) BEGIN
SQL (1.5ms) INSERT INTO "users" ("email", "encrypted_password", "created_at", "updated_at", "first_name", "last_name", "phone") VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING "id" [["email", "test#example.com"], ["encrypted_password", "$2a$11$VEVjSrnc5Y5c8ofXvNmlMOHrS.v4tQuBoKMLdHaSOA2S6fiVIHfE."], ["created_at", 2016-10-17 07:16:55 UTC], ["updated_at", 2016-10-17 07:16:55 UTC], ["first_name", "John"], ["last_name", "Smith"], ["phone", "0340239402309"]]
(139.1ms) COMMIT
(0.1ms) BEGIN
SQL (0.4ms) UPDATE "users" SET "sign_in_count" = $1, "current_sign_in_at" = $2, "last_sign_in_at" = $3, "current_sign_in_ip" = $4, "last_sign_in_ip" = $5, "updated_at" = $6 WHERE "users"."id" = $7 [["sign_in_count", 1], ["current_sign_in_at", 2016-10-17 07:16:55 UTC], ["last_sign_in_at", 2016-10-17 07:16:55 UTC], ["current_sign_in_ip", "::1/128"], ["last_sign_in_ip", "::1/128"], ["updated_at", 2016-10-17 07:16:55 UTC], ["id", 17]]
(0.3ms) COMMIT
Redirected to http://localhost:3000/
Completed 302 Found in 319ms (ActiveRecord: 141.7ms)
I realise that devise does a whole bunch of other stuff besides simply recording the user data, so it may be better to rather move these actions to the Devise User::RegistrationController, and then tweak the accepted params. But how do you override Devise so that it doesn't auto use the devise create method the second you click the submit button, and would instead use a getting_started_create action?
First off getting started is a pretty horrible name for a controller since it is not a noun. You can't say a getting started. So lets change it to QuickstartsController.
Lets setup the routes for this resource:
Rails.application.routes.draw do
# These are your "normal" devise routes
devise_for :users
# This is the mapping for the "quickstart" routes
devise_for :quickstarts,
class_name: 'User',
only: [],
controllers: { registrations: 'quickstarts' }
# These are the actual routes for quickstarts
devise_scope :quickstart do
get "/quickstarts/new", to: "quickstarts#new", as: :new_quickstart
post "/quickstarts", to: "quickstarts#create", as: :quickstarts
end
end
Whenever you are overriding a library controller it is important to take some time to study how the class you are superclassing actually works.
If you look at the Devise controllers almost all the actions have a line like:
yield resource if block_given?
Which lets you tap into the flow of the original implementation by calling super with a block:
class QuickstartsController < Devise::RegistrationsController
# GET /quickstarts/new
def new
# This block is passed to the super class implementation:
super do |resource|
resource.projects.build
end
end
# POST /quickstarts
def create
# You can pass a block here too if you want.
super
end
private
# This should redirect to the newly created project
def after_sign_up_path_for(resource)
polymorphic_path( resource.projects.last )
end
# This is the method Devise devise calls for the params.
def sign_up_params
# Don't write your params sanitiation on one line! Its not cool.
params.require(:user)
.permit(
:first_name, :last_name, :phone, :password, :email,
projects_attributes: [
:user_id, :project_type_id, :name,
:industry_id, :description, :budget_id,
:project_status_id,
feature_ids:[],
addon_ids:[]
]
)
end
end
But how do you override Devise so that it doesn't auto use the devise
create method the second you click the submit button, and would
instead use a getting_started_create action?
Point the form to the correct controller - by passing the url option to form_for.
app/views/quickstarts/new.html.erb:
<h2>Getting Started</h2>
<%= form_for( resource, as: :user, url: quickstarts_path ) do |f| %>
<%= devise_error_messages! %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true %>
</div>
<div class="field">
<%= f.label :password %>
<% if #minimum_password_length %>
<em>(<%= #minimum_password_length %> characters minimum)</em>
<% end %><br />
<%= f.password_field :password, autocomplete: "off" %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "off" %>
</div>
<fieldset>
<legend>Project</legend>
<% f.fields_for :projects do |pf| %>
<%# ... %>
<% end %>
</fieldset>
<div class="actions">
<%= f.submit "Sign up" %>
</div>
<% end %>
Related
I'm stuck in a rails project trying to save a has_one model when the user signs up with Devise.
My app is saving the child model as well as the new user but the issue is that it doesn't save the child id in the user table.
I've tried plenty of options found on Stackoverflow without success.
Am I doing something wrong?
User model:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :omniauthable, :omniauth_providers => [:linkedin]
# Associations
has_one :build, inverse_of: :user
# Allow saving of attributes on associated records through the parent,
# :autosave option is automatically enabled on every association
accepts_nested_attributes_for :build, allow_destroy: true
end
build model
class Build < ActiveRecord::Base
belongs_to :user, inverse_of: :build
has_one :template
# validates_presence_of :user
end
Registrations Controller
class Users::RegistrationsController < Devise::RegistrationsController
before_action :sign_up_params, only: [:create]
before_action :account_update_params, only: [:update]
# before_filter :configure_permitted_parameters
# GET /resource/sign_up
def new
# super
# Override Devise default behaviour and create a build as well
build_resource({})
resource.build_build
respond_with self.resource
# #build = #user.builds.build(template_id: params[:template_id], domain_url: params[:domain_url])
end
# POST /resource
def create
super
# #build = current_user.build.build(params[:post])
# #build = #user.build.build(template_id: sign_up_params[:template_id], domain_url: sign_up_params[:domain_url])
# #build.save
UserMailer.welcome_email(#user).deliver unless #user.invalid?
end
# GET /resource/edit
# def edit
# super
# end
# PUT /resource
# def update
# super
# end
# DELETE /resource
# def destroy
# super
# end
# GET /resource/cancel
# Forces the session data which is usually expired after sign
# in to be expired now. This is useful if the user wants to
# cancel oauth signing in/up in the middle of the process,
# removing all OAuth session data.
# def cancel
# super
# end
# protected
#
# def configure_permitted_parameters
# devise_parameter_sanitizer.for(:sign_up) { |u|
# u.permit(:first_name, :last_name, :email, :password, :password_confirmation, :builds_attributes => [:template_id, :domain_url])
# }
# end
# If you have extra params to permit, append them to the sanitizer.
# def configure_sign_up_params
# devise_parameter_sanitizer.permit(:sign_up, keys: [:attribute])
# end
# If you have extra params to permit, append them to the sanitizer.
# def configure_account_update_params
# devise_parameter_sanitizer.permit(:account_update, keys: [:attribute])
# end
# The path used after sign up.
# def after_sign_up_path_for(resource)
# super(resource)
# end
# The path used after sign up for inactive accounts.
# def after_inactive_sign_up_path_for(resource)
# super(resource)
# end
private
def sign_up_params
devise_parameter_sanitizer.sanitize(:sign_up)
params.require(:user).permit(:first_name, :last_name, :email, :password, :password_confirmation, build_attributes: [:template_id, :domain_url])
end
def account_update_params
params.require(:user).permit(:first_name, :last_name, :email, :password, :password_confirmation, :current_password)
end
end
New User Form - View
<div class="container">
<h4 class="center-align">Sign up</h4>
<div id="signup-row" class="row z-depth-2">
<div id="signup" class="col s6">
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div class="field">
<%= f.label :first_name %><br/>
<%= f.text_field :first_name, autofocus: true %>
</div>
<div class="field">
<%= f.label :last_name %><br/>
<%= f.text_field :last_name %>
</div>
<div class="field">
<%= f.label :email %><br/>
<%= f.email_field :email %>
</div>
<div class="field">
<%= f.label :password %>
<% if #minimum_password_length %>
<em>(<%= #minimum_password_length %>
characters minimum)</em>
<% end %><br/>
<%= f.password_field :password, autocomplete: "off" %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br/>
<%= f.password_field :password_confirmation, autocomplete: "off" %>
</div>
<div class="actions">
<%= f.submit "Sign up", :class => 'btn black' %>
<%= render "devise/shared/links" %>
</div>
<%= f.fields_for :build do |o| %>
<%= o.hidden_field :template_id, value: params["template"] %>
<%= o.hidden_field :domain_url, value: params["domain"] %>
<% end %>
<% end %>
</div>
<div id="linkedin-signup" class="col s6">
<div class="center-align">
<h5>Sign up with LinkedIn </h5> <br>
<%= image_tag('linkedin.png', :class => "linkedIn-logo" ) %>
</div>
</div>
</div>
</div>
Server /post log
Started POST "/users" for 127.0.0.1 at 2016-08-03 13:31:22 +1000
Processing by Users::RegistrationsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"11DgWCU07EXLJKXbhWah0gREdBiN2PLkF/WxWsuqW5rgQdCUrRH9rLBrKpbusRhtsCzSAQT0ADlxhQxMvWAD6A==", "user"=>{"first_name"=>"john", "last_name"=>"maksksk", "email"=>"jofff#gmail.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "build_attributes"=>{"template_id"=>"1", "domain_url"=>"dddddd.com.au"}}, "commit"=>"Sign up"}
(0.1ms) BEGIN
User Exists (0.6ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = 'jofff#gmail.com' LIMIT 1
SQL (0.5ms) INSERT INTO "users" ("first_name", "last_name", "email", "encrypted_password", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id" [["first_name", "john"], ["last_name", "maksksk"], ["email", "jofff#gmail.com"], ["encrypted_password", "$2a$11$WgJJ.uM2DfaqQhUYatUZnuIJmaqIDVfIuYEkl/U3zSbm.h/OH/yGa"], ["created_at", "2016-08-03 03:31:22.796589"], ["updated_at", "2016-08-03 03:31:22.796589"]]
SQL (0.2ms) INSERT INTO "builds" ("template_id", "domain_url", "user_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["template_id", 1], ["domain_url", "dddddd.com.au"], ["user_id", 30], ["created_at", "2016-08-03 03:31:22.800033"], ["updated_at", "2016-08-03 03:31:22.800033"]]
(1.3ms) COMMIT
(0.1ms) BEGIN
SQL (0.4ms) UPDATE "users" SET "last_sign_in_at" = $1, "current_sign_in_at" = $2, "last_sign_in_ip" = $3, "current_sign_in_ip" = $4, "sign_in_count" = $5, "updated_at" = $6 WHERE "users"."id" = $7 [["last_sign_in_at", "2016-08-03 03:31:22.804259"], ["current_sign_in_at", "2016-08-03 03:31:22.804259"], ["last_sign_in_ip", "127.0.0.1/32"], ["current_sign_in_ip", "127.0.0.1/32"], ["sign_in_count", 1], ["updated_at", "2016-08-03 03:31:22.805380"], ["id", 30]]
(1.2ms) COMMIT
Thanks for your help!!
ps: build wasn't a smart name for a table I guess...
Thomas
The problem is that user saved first and then you saved build for relationship purpose you can save user_id to build table instead of saving build_id to user
params.require(:user).permit(:first_name, :last_name, :email, :password, :password_confirmation, build_attributes: [:id, :template_id, :domain_url])
build_attributes should has :id
making a test
def create
user = User.new(sign_up_params)
user.save
end
model User.rb
has_one :build
accepts_nested_attributes_for :build, allow_destroy: true
rails console
user = User.new(name: 'example', build_attributes:{template_id:1, domain_url: 'test'})
user.save # this will create user and after that will create has_one build association
user.errors unless user.save
I'm trying to login with Devise, but the login fails with a 406 Not Acceptable message from Rails 4. Specifically:
Started POST "/login.user" for 127.0.0.1 at 2015-04-03 14:37:21 -0600
Processing by Devise::SessionsController#create as
Parameters: {"utf8"=>"✓",
"authenticity_token"=>"RLOQtv2L80h1VnMKynBuGsqsTEoggZzk3dWk6h8WdfQLOaOcoznTsPDortDQD5ql8qHm52l3+qnAxTf6U+dLxQ==",
"user"=>{"email"=>"jack#example.com",
"password"=>"[FILTERED]",
"remember_me"=>"0"},
"commit"=>"Log in"}
User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."email" = $1 ORDER BY "users"."id" ASC LIMIT 1 [["email", "jack#example.com"]]
(0.2ms) BEGIN
Role Load (0.4ms) SELECT "roles".* FROM "roles" INNER JOIN "unities" ON "roles"."id" = "unities"."role_id" WHERE "unities"."user_id" = $1 AND (((roles.name = 'nil') AND (roles.resource_type IS NULL) AND (roles.resource_id IS NULL))) [["user_id", 4]]
SQL (0.5ms) UPDATE "users" SET "last_sign_in_at" = $1, "current_sign_in_at" = $2, "sign_in_count" = $3, "updated_at" = $4 WHERE "users"."id" = $5 [["last_sign_in_at", "2015-04-03 20:27:03.080761"], ["current_sign_in_at", "2015-04-03 20:37:21.763619"], ["sign_in_count", 7], ["updated_at", "2015-04-03 20:37:21.797872"], ["id", 4]]
(1.7ms) COMMIT
Completed 406 Not Acceptable in 160ms (ActiveRecord: 6.0ms)
I am trying to adapt the Sessions Controller I found here; these are the relevant parts:
class Users::SessionsController < DeviseController
prepend_before_filter :require_no_authentication, only: [:new, :create]
prepend_before_filter :allow_params_authentication!, only: :create
prepend_before_filter :verify_signed_out_user, only: :destroy
prepend_before_filter only: [:create, :destroy] { request.env["devise.skip_timeout"] = true }
# GET /resource/sign_in
def new
self.resource = resource_class.new(sign_in_params)
clean_up_passwords(resource)
yield resource if block_given?
respond_with(resource, serialize_options(resource))
end
# POST /resource/sign_in
def create
self.resource = warden.authenticate!(auth_options)
set_flash_message(:notice, :signed_in) if is_flashing_format?
sign_in(resource_name, resource)
yield resource if block_given?
respond_with resource, location: after_sign_in_path_for(resource)
end
end
Here are the relevant routes:
Prefix Verb URI Pattern Controller#Action
new_user_session GET /login(.:format) devise/sessions#new
user_session POST /login(.:format) devise/sessions#create
destroy_user_session GET /sign_out(.:format) users/sessions#destroy
My sessions/new.html.erb view uses this form:
<%= form_for(resource, as: resource_name, url: user_session_path(resource_name)) do |f| %>
<input name="authenticity_token"
type="hidden"
value="<%= form_authenticity_token %>"/>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true %>
</div>
<div class="field">
<%= f.label :password %><br />
<%= f.password_field :password, autocomplete: "off" %>
</div>
<% if devise_mapping.rememberable? -%>
<div class="field">
<%= f.check_box :remember_me %>
<%= f.label :remember_me %>
</div>
<% end -%>
<div class="actions">
<%= f.submit "Log in" %>
</div>
<% end %>
Notice I added the hidden authenticity_token in an attempt to address the 406 Not Acceptable message (I also have <%= csrf_meta_tags %> in my application.html.erb view), and from the POST I can see it's being sent.
My user model has devise: :database_authenticatable and validates_presence_of :email, :password.
I appreciate any tips or suggestions! I've tried many suggestions and there is a similar question here. I can provide any other info that might help.
I solved this problem by using the 'omniauth-google-oauth2'gem.
Latest
I have switched to Simple form. No problem with permitting date attributes there.
Recent attempts
I have put a demo repository on Github illustrating the problem:
This one uses formtastic and displays my problem with:
Unpermitted parameters: date_of_receipt(1i), date_of_receipt(2i), date_of_receipt(3i), date_of_receipt(i)
https://github.com/bigos/permit_date_selector/commit/9f142b79c51e71dca35c988125a2912b83b91972
This one doesn't use formtastic and works fine;
https://github.com/bigos/permit_date_selector/commit/4c53b934ac5cd3f04241bf462e7b677ef5d28335
Initial post
When I try to submit my form I get this message
Unpermitted parameters: date_of_receipt(i)
I have :date_of_receipt in the list of permitted parameters.
My form input selecting the date looks as follows:
<%= f.input :date_of_receipt, as: :date_select %>
Should I give up on formtastic and go back to standard forms?
I've created a fresh Rails app (using Rails 4.1.5 and Formtastic 2.3.1) to try to replicate, and I can't, so I'm closing. Here's what I had:
# Migration
class CreatePosts < ActiveRecord::Migration
def change
create_table :posts do |t|
t.string :title
t.string :body
t.datetime :published_at
t.timestamps
end
end
end
# Model
class Post < ActiveRecord::Base
end
# Controller
class PostsController < ApplicationController
def new
#post = Post.new
end
def create
#post = Post.new(post_params)
if #post.save
redirect_to #post
else
render :new
end
end
def show
#post = Post.find(params[:id])
end
protected
def post_params
params[:post].permit(:title, :body, :published_at)
end
end
# View
<%= semantic_form_for #post do |f| %>
<%= f.inputs do %>
<%= f.input :title %>
<%= f.input :body %>
<%= f.input :published_at %>
<% end %>
<%= f.actions do %>
<%= f.action :submit %>
<% end %>
<% end %>
By simply permitting :published_at, I was able to successfully save a Post into the database with the time I had selected. Here's the development.log:
Started POST "/posts" for 127.0.0.1 at 2014-09-06 21:13:37 +1000
Processing by PostsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"Jv4Pd7aNgvjkCtzrX+gHNeCNfX3L8t6IpEOEAWzdeIo=", "post"=>{"title"=>"sdfgs", "body"=>"sdgfdfg", "published_at(1i)"=>"2019", "published_at(2i)"=>"1", "published_at(3i)"=>"1", "published_at(4i)"=>"00", "published_at(5i)"=>"01"}, "commit"=>"Create Post"}
(0.1ms) begin transaction
SQL (0.2ms) INSERT INTO "posts" ("body", "created_at", "published_at", "title", "updated_at") VALUES (?, ?, ?, ?, ?) [["body", "sdgfdfg"], ["created_at", "2014-09-06 11:13:37.685160"], ["published_at", "2019-01-01 00:01:00 .000000"], ["title", "sdfgs"], ["updated_at", "2014-09-06 11:13:37.685160"]]
(8.8ms) commit transaction
Redirected to http://localhost:3000/posts/3
Completed 302 Found in 12ms (ActiveRecord: 9.1ms)
There's no extra trickery required, this is how you do it :)
When you inspect the element on the page, you will see three different elements for date_select.
model[date_of_receipt(1i)], model[date_of_receipt(2i)], model[date_of_receipt(3i)]
So you will have to permit
date_of_receipt(1i), date_of_receipt(2i), date_of_receipt(3i)
in your controller
I am using a custom controller to handle Devise actions.
class RegistrationsController < Devise::RegistrationsController
def new
#joining_group = params[:access_token]
session[:access_token] = params[:access_token]
super
end
def create
super
sign_in resource_name, resource # sign in the user so that the code below works
if params[:organization] # User is an admin and creates group
current_user.admin = true
new_group = Group.create( name: params[:organization], access_token: SecureRandom.hex ) # add super secret token to group so other users can be invited to join
current_user.group = new_group
current_user.save!
else # user is joining vis a vis email invitation with access_token
current_user.group_id = Group.where( access_token: session[:access_token] ).first.id
current_user.save!
end
end
def update
super
end
def group_params
params.require(:group).permit(:name)
end
end
However, when I try to create a new user I get the following error in my browser when I have an empty input tag (if all inputs are filled the create works just fine):
NoMethodError in RegistrationsController#create
undefined method `admin=' for nil:NilClass
Extracted source (around line #12):
10 super
11 if params[:organization] # User is an admin and creates group
12 current_user.admin = true
13 new_group = Group.create( name: params[:organization], access_token: SecureRandom.hex )
14 current_user.group = new_group
15 current_user.save!
The validatable module is turned on in my user class. My registration/new.html.erb view is as such:
<div class="logo">
<h1>VitalTracker</h1>
</div>
<div class="registration_box">
<% if #joining_group %>
<h2>Join Group</h2>
<% else %>
<h2>Create Account</h2>
<% end %>
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div>
<%= f.email_field :email, :autofocus => true, placeholder: "Email", class: "registration_input" %>
</div>
<div>
<%= f.password_field :password, placeholder: "Password", class: "registration_input" %>
</div>
<div>
<%= f.password_field :password_confirmation, placeholder: "Confirm Password", class: "registration_input" %>
</div>
<div>
<%= f.text_field :name, placeholder: "Name", class: "registration_input" %>
</div>
<% unless #joining_group %>
<div>
<%= text_field_tag "organization", nil, placeholder: "Organization", class: "registration_input" %>
</div>
<% end %>
<div>
<%= f.submit "Create Account", class: "registration_btn large_btn" %>
</div>
<% end %>
<%= render "devise/shared/links" %>
</div>
Server log below:
Started POST "/users" for 127.0.0.1 at 2014-02-22 16:05:56 -0500
Processing by RegistrationsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"eBTmAyknoi92qdbhiirlUfjjtbdOiD8jzYwp6ZE9dwI=", "user"=>{"email"=>"", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "name"=>""}, "organization"=>"", "commit"=>"Create Account"}
(0.2ms) BEGIN
(0.2ms) ROLLBACK
Rendered devise/shared/_links.erb (0.3ms)
Rendered registrations/new.html.erb within layouts/application (3.8ms)
(0.2ms) BEGIN
SQL (0.7ms) INSERT INTO "users" ("created_at", "current_sign_in_at", "current_sign_in_ip", "last_sign_in_at", "last_sign_in_ip", "name", "sign_in_count", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING "id" [["created_at", Sat, 22 Feb 2014 21:05:56 UTC +00:00], ["current_sign_in_at", Sat, 22 Feb 2014 21:05:56 UTC +00:00], ["current_sign_in_ip", "127.0.0.1"], ["last_sign_in_at", Sat, 22 Feb 2014 21:05:56 UTC +00:00], ["last_sign_in_ip", "127.0.0.1"], ["name", ""], ["sign_in_count", 1], ["updated_at", Sat, 22 Feb 2014 21:05:56 UTC +00:00]]
(0.6ms) COMMIT
(0.2ms) BEGIN
SQL (0.6ms) INSERT INTO "groups" ("access_token", "created_at", "name", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["access_token", "103ff607863b1f766d3cd1b23d1f57dd"], ["created_at", Sat, 22 Feb 2014 21:05:56 UTC +00:00], ["name", ""], ["updated_at", Sat, 22 Feb 2014 21:05:56 UTC +00:00]]
(0.4ms) COMMIT
(0.2ms) BEGIN
(0.2ms) ROLLBACK
Completed 422 Unprocessable Entity in 94ms
ActiveRecord::RecordInvalid (Validation failed: Email can't be blank):
app/controllers/registrations_controller.rb:17:in `create'
Rendered /Users/jonathantrope/.rvm/gems/ruby-2.0.0-p353#rails4/gems/actionpack-4.0.2/lib/action_dispatch/middleware/templates/rescues/_source.erb (0.8ms)
Rendered /Users/jonathantrope/.rvm/gems/ruby-2.0.0-p353#rails4/gems/actionpack-4.0.2/lib/action_dispatch/middleware/templates/rescues/_trace.erb (1.1ms)
Rendered /Users/jonathantrope/.rvm/gems/ruby-2.0.0-p353#rails4/gems/actionpack-4.0.2/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (1.1ms)
Rendered /Users/jonathantrope/.rvm/gems/ruby-2.0.0-p353#rails4/gems/actionpack-4.0.2/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (19.2ms)
Thanks.
If you want to use current_user, add before_filter :authenticate_user! to your controller. Looking at the source of Devise::RegistrationsController I think you want to use resource instead of current_user.
Btw creating an admin based on the params[:organization] is a bad idea.
current_user is nil because no-one is signed in.
You need something like this:
def create
super
# sign in after registration
sign_in resource_name, resource
# then the rest of your code shuold be ok
if params[:organization] # User is an admin and creates group
current_user.admin = true
# etc
The problem was due to calling current_user.save!, which prevented invalid create error messages to be shown by devise in the view as intended. Using current_user.save fixes it.
Currently implementing Threaded Messaging. via RailsCast
I've installed the Ancestry gem, however all messages that I create are parents. ie.) Ancestry = nil
Even after passing my parent:id to new action
Message Controller
def index
#message = Message.new
#user = current_user
#sent_messages = current_user.sent_messages
#received_messages = current_user.received_messages
end
def new
#message = Message.new
#message.parent_id = params[:parent_id]
end
Index.html
<% for incoming in #received_messages %>
<%= render partial: "message", locals: {incoming: incoming} %>
_message.html.erb
</div>
<%= link_to "Reply", new_message_path(:parent_id => incoming) ,class: "regular" %>
</div>
new.html.erb
<%= form_for #message do |f| %>
<p>
To:<br />
<%= f.hidden_field :parent_id %>
<%= f.hidden_field :recipient, :value => (#message.parent.sender.name) %>
</p>
<p>
Message<br />
<%= f.text_area :body %>
</p>
<p>
<%= submit_tag "Send Threaded Reply" %>
</p>
<% end %>
Message.rb
class Message < ActiveRecord::Base
attr_accessible :recipient, :subject, :body, :parent_id
has_ancestry
end
My console after creating a message:
Key point - I'm passing the parent_id (144) in Message however ancestry still passes as nil.
Parameters: {"utf8"=>"✓", "authenticity_token"=>"gKVr06oT+6OcAERHAzSX79vTlJLniofmEOjZPdZmfwM=", "message"=>{**"parent_id"=>"114"**, "recipient"=>"Rach Miller", "body"=>"meh and more meh"}, "commit"=>"Send Threaded Reply"}
User Load (0.6ms) SELECT "users".* FROM "users" WHERE "users"."id" = 17 LIMIT 1
User Load (0.6ms) SELECT "users".* FROM "users" WHERE "users"."name" = 'Rach Miller' LIMIT 1
(0.2ms) BEGIN
SQL (0.7ms) INSERT INTO "messages" ("ancestry", "body", "created_at", "read_at", "recipient_deleted", "recipient_id", "sender_deleted", "sender_id", "subject", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) RETURNING "id" [["ancestry", nil], ["body", "meh and more meh"], ["created_at", Tue, 20 Aug 2013 03:14:15 UTC +00:00], ["read_at", nil], ["recipient_deleted", false], ["recipient_id", 18], ["sender_deleted", false], ["sender_id", 17], ["subject", nil], ["updated_at", Tue, 20 Aug 2013 03:14:15 UTC +00:00]]
After Bigxiang's comment, I decided to take a look at my create function.
I have been passing my params individually, So using
#message.parent_id = params[:message][:parent_id] worked for me
Cheers