Can not save user sign up info when using devise and wicked - ruby-on-rails-4

Im new to the rails platform...i have an issue of saving user sign up information on clicking register in my form....i get no error but on checking the rails console all the user information is equated to nil...cant figure out why.
my user steps controller code
class UserStepsController < ApplicationController
include Wicked::Wizard
steps :finishing_step
def show
#user = current_user
render_wizard
end
def update
#user = current_user
if #user.save
redirect_to root_path
else
render_wizard
end
end
def user_params
params.require(:user).permit(:first_name, :middle_name, :last_name, :address_first_line, :address_second_line, :city, :nationality)
end
private
def redirect_to_finish_wizard
redirect_to root_path, notice: "Thanks for signing up."
end
end
below is the code for the users controller
class UsersController < ApplicationController
def create
#user = User.new(params[:user])
if #user.save
redirect_to root_path
else
render_wizard
end
end
end
here below is the code for my simple form with user sign up information
<%= form_for User.new, url: wizard_path do |f| %>
<div><%= f.label :first_name, "First Name" %><br />
<%= f.text_field :first_name %></div>
<div><%= f.label :middle_name, "Middle Name" %><br />
<%= f.text_field :middle_name %></div>
<div><%= f.label :last_name, "Last Name" %><br />
<%= f.text_field :last_name %></div>
<div><%= f.label :phone_number, "Phone Number" %><br />
<%= f.text_field :phone_number %></div>
<div><%= f.label :date_of_birth, "Date of Birth" %><br />
<%= f.date_select :date_of_birth, start_year: 1900 %></div>
<div><%= f.label :address_first_line, "Address (first line)" %><br />
<%= f.text_field :address_first_line %></div>
<div><%= f.label :address_second_line, "Address (second line)" %><br />
<%= f.text_field :address_second_line %></div>
<div><%= f.label :city, "City" %><br />
<%= f.text_field :city %></div>
<div><%= f.label :nationality, "Nationality" %><br />
<%= country_select(:user, :nationality, {selected: "UG"}) %></div>
<div>
<%= f.label :avatar %>
<%= f.file_field :avatar %>
</div>
<div>
<%= f.label :terms_of_service, "Agree to Terms of Service" %> <br>
<%= f.check_box :terms_of_service %>
</div>
<%= f.submit "Register", class: "btn btn-primary" %>
<% end %>
for any help thanks in advance

I think there is some mistakes in your conception.
The wizard operates AFTER the sign_up of your user.
So basically, you need to create your user first without the wizard.
Creation of your User
If you're using Devise with your model User, you already have a User Controller somewhere. Actually, your class UsersController is useless if you are using Devise.
So if you want to redirect to your wizard step after the sign up, then you need to override the Devise registration controller (doc: Redirect to specific page).
To do so, create a new controller like this:
class RegistrationsController < Devise::RegistrationsController
protected
def after_sign_up_path_for(resource)
user_steps_path(:finishing_step) #add proper route
end
end
I don't have the content of your config/route.rb file but you need to have something like this :
resources :user_steps
Adding steps
Wicked wizard works like this:
- One controller with 2 actions (show and update)
- N views for N steps (1 step = 1 view, 42 steps = 42 views)
You can access the name of your current step in the actions show and update using step.
render_wizard render the view of the current step
render_wizard #user render the next step view (or the current step view if there is any error)
Using strong parameters
In your controller, you never use user_params.
So in your update action, you never the your #user with the parameters from your form. current_user doesn't call user_params for you.
Also, there is a big difference between save and update_attributes and I think you want to use the second in your update action.
It's better to place user_params in the private section also.
Final form of your controller
Your controller should look like that I guess:
class UserStepsController < ApplicationController
include Wicked::Wizard
steps :finishing_step
def show
#user = current_user
render_wizard
end
def update
#user = current_user
if #user.update_attributes(user_params)
# because you only have one step, you don't need render_wizard #user
redirect_to_finish_wizard
else
render_wizard
end
end
private
def user_params
params.require(:user).permit(:first_name, :middle_name, :last_name, :address_first_line, :address_second_line, :city, :nationality)
end
def redirect_to_finish_wizard
redirect_to root_path, notice: "Thanks for signing up."
end
end
Read the doc
I think you miss some tips in the wicked doc.
Maybe you should re-read it.
Wicked doc

Related

Using hstore and saving new values for user

My user model contains values for things like:
name, email, phone, approved, etc..
The scope of the project I am working on includes custom user settings and for this reason I am using hstore (I dont want to create a user_settings table).
On the user edit view I want to create a checkbox called 'colors' and whether or not the checkbox is checked determines if that setting is set for the user or not.
I have already setup hstore as follows:
class AddHstore < ActiveRecord::Migration
def up
enable_extension :hstore
end
def down
disable_extension :hstore
end
end
And updated the User model as follows:
class AddSettingsToUser < ActiveRecord::Migration
def up
add_column :users, :settings, :hstore
end
def down
remove_column :users, :settings
end
end
This is essentially my user edit view:
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put, :class => "form-horizontal user" }) do |f| %>
<%= devise_error_messages! %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name, autofocus: true %>
</div>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email %>
</div>
<div class="field">
<%= f.label :phone_number %><br />
<%= f.text_field :phone_number %>
</div>
<div class="actions">
<%= f.submit 'Update', :class => 'btn btn-primary' %>
</div>
<% end %>
At this point I am unsure as to how to actually implement this functionality. The user edit page allows the user to change their name, phone and other values but how would I include a new value for the hstore settings?
Inside the form_for from where you are creating users, add your hstore fileds like below :
<%= form_for resource, ...do |f| %>
#...
<%= f.fields_for :settings do |settings| %>
<%= settings.text_field :field1 %>
<%= settings.text_field :field2 %>
<% end %>
#....
<% end %>
Then update your controller strong parameter method like below to permit these new fields.:
def user_params
params.require(:user)
.permit(
:name,
:email,
settings: [ :field1, :field2 ]
)
end
Now, you are done. Open your rails console and try some sample data like
User.create(
settings: { field1: 'data1', field2: 'data2' }
)

undefined method `send_activation_email'

after a few additions to my code (that didn't actually touch any of the code that's raising the issue now) a specific part of my sign-up process stopped working.
This part is from Michael Hartl's tutorial, and it had worked fine but now is raising me a problem whenever I try to sign-up a new user through a normal sign-up form (I added signups through FB G+ and Linkedin and they all work).
I get a undefined method `send_activation_email' when submit the form. I didn't check the method for some time as I was adding the other signups for social media, but these have their own paths and work through the sessions controller, not the users controller so they shouldn't really create a problem.
In my user model I have:
def send_activation_mail
UserMailer.account_activation(self).deliver_now
end
Then in my users controller:
def create
#user = User.new(user_params)
if #user.save
#user.send_activation_email
flash[:info] = "Please check your email to activate your account."
redirect_to root_url
else
render 'new'
end
end
And the view that generates the form:
<div class="row center">
<div class="col-md-4 center mg-top col-md-offset-4">
<%= form_for(#user) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.label :first_name %>
<%= f.text_field :first_name, class: 'form-control' %>
<%= f.label :last_name %>
<%= f.text_field :last_name, class: 'form-control' %>
<%= f.label :email %>
<%= f.email_field :email, class: 'form-control' %>
<%= f.label :password %>
<%= f.password_field :password, class: 'form-control' %>
<%= f.label :password_confirmation, "Re-type your password" %>
<%= f.password_field :password_confirmation, class: 'form-control' %>
<%= f.submit "Create an account", class: "btn btn-primary margin-25" %>
<% end %>
</div>
</div>
Whenever I sign-up a new user, the post action goes through and the user is actually created but I get this Action Controller error:
undefined method `send_activation_email' for #<User:0x007f90064bd5a0>
Extracted source (around line #19):
17
18
19
20
21
22
#user = User.new(user_params)
if #user.save
#user.send_activation_email
flash[:info] = "Please check your email to activate your account."
redirect_to root_url
else
A read-out from ruby's console tells me the user has been created (and the error is raised in the conditional if-save ...):
#<User id: 133, first_name: "Txe", last_name: "Pah", email: "teste#email.com", password_digest: "$2a$10$PLY4ZleCtUO0cLdRjIErBuF0j46YQBq1g3Krsf5T.i8...", created_at: "2015-07-25 03:41:49", updated_at: "2015-07-25 03:41:49", remember_digest: nil, admin: false, activation_digest: "$2a$10$voHnNYgzI2jazwRK3EiM6uKsel8Fieb.9HEVs29X8ml...", activated: false, activated_at: nil, reset_digest: nil, reset_sent_at: nil, link: nil, fb: false, fb_id: nil, fb_image: nil, gplus: false, gplus_id: nil, gplus_image: nil, lin: false, lin_id: nil, lin_image: nil, gender: "Unidentified", avatar: nil>
What I don't get is why the send_activation_email is not working as it is defined in the User model.
Could somebody help me or has experienced the same problem?
You have send_activation_mail in User model not send_activation_email. Changing it to
#user.send_activation_mail
should solve your problem.

Remove avatar - carrierwave and devise

I'm having an unbelievable amount of trouble getting the Carrierwave :remove_avatar checkbox to work in my Devise profile edit form. I've been following the carrierwave documentation and wiki.
I've mounted the uploader to the User model. I've added :avatar and :remove_avatar to in the ApplicationController sanitizer
application_controller.rb
def configure_permitted_parameters
devise_parameter_sanitizer.for(:account_update) do |u|
u.permit(:first_name, :last_name, :email,
:password, :password_confirmation, :avatar, :remove_avatar)
end
devise_parameter_sanitizer.for(:sign_up) do |u|
u.permit(:first_name, :last_name, :email,
:password, :password_confirmation)
end
end
I've added the :remove_avatar to the edit form
/devise/registrations/edit.html.erb
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put, multipart: true }) do |f| %>
<%= f.label :avatar %><br />
<%= image_tag(resource.avatar_url(:thumb)) %>
<%= f.file_field :avatar, accept: 'image/jpeg,image/png' %>
<label>
<%= f.check_box :remove_avatar %>
Remove avatar
</label>
<%= f.label :first_name %><br />
<%= f.text_field :first_name, autofocus: true %>
<%= f.label :last_name %><br />
<%= f.text_field :last_name %>
<%= f.label :email %><br />
<%= f.email_field :email %>
<div><%= link_to 'Cancel', resource %> <%= f.submit "Update" %></div>
<% end %>
I'm not having any other problems with carrierwave except for removing the avatars. When I check the box and submit the form the picture is not removed.
I did a test where I used the users controller instead of devise's registrations controller and submitted the form to #user instead of resource and I was able to get it working. I'd rather stick to convention and use the registrations controller. What am I doing wrong or missing?
#user.remove_avatar!
#user.remove_avatar = true
#user.save
#user.reload
Try this, May help you.
Use this in your model:
after_commit :remove_avatar!, on: :destroy

Rendering sign-in view giving error

Controller code
class AuthenticationController < ApplicationController
def sign_in
#user=User.new
end
def login
username_or_email=params[:user][:username]
password=params[:user][:password]
#check for the username or email
if username_or_email.rindex('#')
email=username_or_email
else
email=username_or_email
end
if User.authenticate(email,password)
flash[:notice] = 'Welcome.'
redirect_to :root
else
flash.now[:error] = 'Unknown user. Please check your username and password.'
render "sign_in"
end
Sign-in view Code
<p>Sign In</p>
<%= form_for #user, :as => :user, :url => sign_in_path(#user) do |f| %>
<p>
<%= f.label 'username or email:' %><br />
<%= f.text_field :username %>
</p>
<p>
<%= f.label 'password:' %><br />
<%= f.password_field :password %>
</p>
<p>
<%= f.submit 'Sign In' %>
<%= f.submit 'Clear Form', :type => 'reset' %>
</p>
<% end %>
Error:-
First argument in form cannot contain nil or be empty when I am rendering Sign_In form after the user is not authorised.

First argument cannot contain nil or be empty rails 4

I'm making a single page application based on Futureme.org for practice. The user goes to the home page, sees a form to put their email address, subject, and the body of their message and sends it.
The problem I am having is I get an error "First argument in form cannot contain nil or be empty". Here is my code;
Model;
class Letter < ActiveRecord::Base
VALID_EMAIL_REGEX = /\A[\w+\-,]+#[a-z\d\-.]+\.[a-z]+\z/i
validates_presence_of :email, presence: true, format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
validates_length_of :subject, presence: true, length: { maximum: 50 }
validates_presence_of :message
end
Controller;
class LettersController < ApplicationController
def new
#letter = Letter.new
end
def create
#letter = Letter.new(params[:letter])
if #letter.save
redirect_to letters_path, :notice => "Your letter was sent!"
else
render "new"
end
end
end
View form;
<%= form_for #letter, :html => {:class => 'form-horizontal'} do |f| %>
<% if #letter.errors.any? %>
<div class="error_messages">
<h2><%= pluralize(#letter.errors.count, "error")%>stopped this message from being saved</h2>
<ul>
<% #letter.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
<% end %>
<div class="field">
<%= f.label :email %><br />
<%= f.text_field :email %>
</div>
<div class="field">
<%= f.label :subject %><br />
<%= f.text_field :subject %><br />
</div>
<div class="field">
<%= f.label :message, "Message" %><br />
<%= f.text_area :message, size: "60x10" %>
</div>
<div class="actions"><%= f.submit "Submit", class: "btn btn-small btn-primary" %></div>
<% end %>
The form is on the home page which is in the "Welcome Controller".
Any help would be great.
It looks like you build letter in action new when form is drawn on other view :)
You should move #letter = Letter.new to appropriate action
One of the variant is:
#WelcomeController
def home
#letter = Letter.new
end
#LettersController
def create
#letter = Letter.new(params[:letter])
if #letter.save
redirect_to letters_path, :notice => "Your letter was sent!"
else
render "welcome/home"
end
end
be careful if you prepare some data in action home you should care about initializing them for action create when validation failed because you render "welcome/home" view