Form data not getting saved to database - ruby-on-rails

I'm new to RoR and I'm trying to create a sign-up form. When I click on 'Create my account', data does not get saved to the database. I have added resources: users to my routes file. Is there something else I'm missing?
This is my view (signup.html.erb)
Sign Up
<%= form_for #user, :url => { :action => "create" } do |f| %>
<%= f.label :emp_id,"Employee ID" %><br>
<%= f.text_field :emp_id, class: 'form-control' %><br><br>
<%= f.label :password, "Password" %><br>
<%= f.password_field :password, class: 'form-control' %><br><br>
<%= f.label :password_confirmation, "Password Confirmation" %><br>
<%= f.password_field :password_confirmation, class: 'form-control' %><br><br>
<%= f.submit "Create my account", class: "btn btn-primary" %>
<% end %>
This is my controller
class UsersController < ApplicationController
def new
#user = User.new
end
def signup
#user = User.new
end
def show
#user = User.find(params[:id])
end
def create
#user = User.new(user_params)
if #user.save
render 'login'
else
render 'signup'
end
end
def user_params
params.require(:user).permit(:emp_id, :password)
end
end

You need to permit :password_confirmation
def user_params
params.require(:user).permit(:emp_id, :password, :password_confirmation)
end
And make sure there are no other validations like email presence or that will cause validations to fail

Related

ActionController::ParameterMissing: param is missing or the value is empty: user - Don't understand

Ok, so I have seen the other threads relating to this issue, but so far I haven't had any luck in solving it following their advice.
I'm trying to test for unsuccessful edits, but I am consistently having an error where the param is missing for 'user'.
Here is the controller code:
class UsersController < ApplicationController
def new
#user = User.new
end
def show
#user = User.find(params[:id])
end
def create
#user = User.new(user_params)
if #user.save
log_in #user
flash[:success] = "Welcome to the Site!"
redirect_to #user
else
render 'new'
end
end
def edit
#user = User.find(params[:id])
end
def update
#user = User.find(params[:id])
if #user.update_attributes(user_params)
else
render 'edit'
end
end
private
def user_params
params.require(:user).permit(:name, :email, :password, :password_confirmation)
end
end
View:
<% provide(:title, "Edit User") %>
<% provide(:button_text, "Save changes") %>
<h1>Edit your profile </h1>
<div class="row">
<div class="col-md-6 col-md-offset-3 well">
<%= render 'shared/form' %>
<div class="gravatar_edit">
<%= gravatar_for #user %>
Change
</div>
</div>
</div>
And here is the test I have for unsuccessful edits:
require 'test_helper'
class UsersEditTest < ActionDispatch::IntegrationTest
def setup
#user = users(:robert)
end
test "unseccessful edit" do
get edit_user_path(#user)
assert_template 'users/edit'
patch user_path(#user), params: { user: { name: "",
email: "invalid#invalid.org",
password: "in ",
password_confirmation: " valid" } }
assert_template 'users/edit'
end
end
Now, I have tried removing (user_params) from if #user.update_attributes, but it makes no difference. I've also removed .requre(:user) from def params, but that only causes many more errors.
Edit
Here is the form I'm using:
<%= form_for(#user) do |f| %>
<%= render 'shared/error_messages', object: #user %>
<%= f.label :name %>
<%= f.text_field :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 %>
<%= f.password_field :password_confirmation, class: 'form-control' %>
<%= f.submit yield(:button_text), class: 'btn btn-primary' %>
<% end %>

Rails - Register a user in stages. Starting with username

I want to change my user registration. Instead of letting the users fill in all the details at once I would like the user to fill in only the username and bring him to the registration page with the username filled in and he has to add the rest of the details.
What I have now at my landingpage (basically copy of the new user page):
<%= form_for(#user) do |f| %>
<%= render 'shared/error_messages' %>
<%= f.label :name, "Username" %>
<%= f.text_field :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, "Confirmation" %>
<%= f.password_field :password_confirmation, class: 'form-control' %>
<%= f.submit "Create my account", class: "btn btn-success btn-md createbutton"%>
<% end %>
My registration page is at registation_path
<% provide(:title, 'Register') %>
<div class = "container center">
<body class ="formbody">
<center><h1>Sign up</h1></center>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_for(#user) do |f| %>
<%= render 'shared/error_messages' %>
<%= f.label :name %>
<%= f.text_field :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, "Confirmation" %>
<%= f.password_field :password_confirmation, class: 'form-control' %>
<%= f.submit "Create my account", class: "btn btn-success createbutton"%>
</div>
</div>
</div>
<% end %>
</body>
I would like the user to fill in the name in 1 form at the landing page and get redirected to the registration form with the name filled in.
edit: added the controller
class UsersController < ApplicationController
before_action :logged_in_user, only: [:index, :edit, :update]
before_action :correct_user, only: [:edit, :update]
def new
#user = User.new
end
def index
#users = User.all
end
def edit
#user = User.find(params[:id])
end
def update
#user = User.find(params[:id])
if #user.update_attributes(user_params)
flash.now[:success] = "Profile updated"
redirect_to #user
else
render 'edit'
end
end
def create
#user = User.new(user_params) # Not the final implementation!
if #user.save
log_in #user
flash.now[:success] = "Account Created Succesfully"
redirect_to #user
else
render 'new'
end
end
def show
#user = User.find(params[:id])
end
def logged_in_user
unless logged_in?
store_location
flash[:danger] = "Please log in."
redirect_to login_url
end
end
# Confirms the correct user.
def correct_user
#user = User.find(params[:id])
redirect_to(root_url) unless current_user?(#user)
end
private
def user_params
params.require(:user).permit(:name, :email, :password,
:password_confirmation)
end
end

Rails map one field in form to two fields in model

I've seen a lot of posts about how to map 2 form fields to one model field, but what about mapping 1 form field to provide answers for two (or more) model fields? I have a form for users which gives a field, last_name, for a user. But I want the default password for that user to also be last_name (and I have password_confirmation set up, so that also needs to be last_name). How would I do this?
Form:
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_for(#user) do |f| %>
<%= f.label :first_name %>
<%= f.text_field :first_name, class: 'form-control' %>
<%= f.label :last_name %>
<%= f.text_field :last_name, :password, :password_confirmation,
class: 'form-control' %>
<%= f.label :email %>
<%= f.email_field :email, class: 'form-control' %>
<%= f.hidden_field :access_level, :value => "Chair" %>
<%= f.label :Phone %>
<%= f.text_field :phone_number, :id => "phone", class: 'form-control' %>
<p> </p>
<div class="col-md-12">
<%= f.submit "Add Chair", class: "btn btn-primary" %>
</div>
<% end %>
</div>
</div>
user_controller.rb
def create
#user = User.new(user_params)
if #user.save
log_in #user
current_user
flash[:success] = "Welcome to the Penn Model Congress!"
redirect_to after_sign_in_path
else
render 'new'
end
end
private
def user_params
params.require(:user).permit(:first_name, :last_name, :email, :password,
:password_confirmation, :access_level,
:phone_number)
end
end
I would add a before_validation callback to the User model like this:
# in app/models/user.rb
before_validation :set_default_password
private
def set_default_password
self.password ||= last_name
self.password_confirmation ||= last_name
end
If this will be your default and you don't want the user to be able to override it on creation, you could set it on the controller:
View:
<%= f.text_field :last_name, class: 'form-control' %>
Controller:
def create
#user = User.new(user_params)
#user.password = #user.last_name
#user.password_confirmation = #user.last_name
if #user.save
log_in #user
current_user
flash[:success] = "Welcome to the Penn Model Congress!"
redirect_to after_sign_in_path
else
render 'new'
end
end

Couldn't find User with id=update_password with Devise

I'm using devise on a Rails application and for various reasons I needed to add a custom password change, using solution 3 from here: https://github.com/plataformatec/devise/wiki/How-To:-Allow-users-to-edit-their-password
I've looked through various other questions and tried augmenting my routes in a number of ways but the url always comes up /users/update_password (without a parameter passed), or /users/update_password.254 (with a parameter passed). I need it to be /users/254/update_password.
Here is the Users Controller I'm working with (relevant methods are update_password and user_params).
class UsersController < ApplicationController
inherit_resources
load_and_authorize_resource
before_filter :authenticate_user!
def destroy
name = #user.to_s
destroy!(notice: "User #{#user.to_s} was deleted.")
end
def edit
#user = current_user
end
def update_password
#user = User.find(current_user.id)
if #user.update_with_password(user_params)
sign_in #user, :bypass => true
redirect_to root_path
else
render "edit"
end
end
private
def build_resource_params
[params.fetch(:user, {}).permit(:name, :email, :phone_number, :password, :password_confirmation).tap do |p|
p[:institution_pid] = build_institution_pid if params[:user][:institution_pid]
p[:role_ids] = build_role_ids if params[:user][:role_ids]
end]
end
def build_institution_pid
institution = Institution.find(params[:user][:institution_pid])
authorize!(:add_user, institution)
institution.id
end
def build_role_ids
[].tap do |role_ids|
roles = Role.find(params[:user][:role_ids].reject &:blank?)
roles.each do |role|
authorize!(:add_user, role)
role_ids << role.id
end
end
end
def user_params
params.required(:user).permit(:password, :password_confirmation, :current_password)
end
end
This is the relevant portion of routes.rb
devise_for :users
resources :users do
collection do
get 'password'
put 'update_password'
end
end
This is the view I created to go with it:
<div class="page-header">
<h1>Change Password</h1>
</div>
<%= form_for(#user, :url => { :action => "update_password" } ) do |f| %>
<div class="field">
<%= f.label :password, "Password" %><br />
<%= f.password_field :password, :autocomplete => "off" %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %>
</div>
<div class="field">
<%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
<%= f.password_field :current_password %>
</div>
<div class="action_container">
<%= f.submit %>
</div>
And this is the link: (currently with a parameter but I've tried without as well)
<li><%= link_to "Change Password", update_password_users_path(current_user) %></li>
When I click that link I get routed to a page that says ActiveRecord::RecordNotFound in UsersController#show, Couldn't find User with id=update_password.
I tried to follow the instructions pretty closely and I've tried to fiddle with the routes a couple times to get it to work and I'm pretty lost at this point. Has anyone seen this before and can help? Thanks!
To achieve what you need, you will have the following routes:
resources :users do
patch 'update_password', on: :collection
get 'edit_password', on: :member
end
Then you'll add a link that would lead user to update password form. The link should look like as follows:
<li><%= link_to "Change Password", edit_password_user_path(current_user) %></li>
The link would lead to users/edit_password.html.erb:
<div class="page-header">
<h1>Change Password</h1>
</div>
<%= form_for(#user, :url => { :action => "update_password" } ) do |f| %>
<div class="field">
<%= f.label :password, "Password" %><br />
<%= f.password_field :password, :autocomplete => "off" %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %>
</div>
<div class="field">
<%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
<%= f.password_field :current_password %>
</div>
<div class="action_container">
<%= f.submit %>
</div>
<% end %>
When form is submitted, that would trigger update_password in UsersController. Here is the code for controller:
class UsersController < ApplicationController
def edit_password
#user = current_user
end
def update_password
#user = User.find(current_user.id)
if #user.update_with_password(user_params)
sign_in #user, :bypass => true
redirect_to root_url
else
render "edit_password"
end
end
private
def user_params
params.required(:user).permit(:password, :password_confirmation, :current_password)
end
end

NoMethodError raised following Railscast #250

I'm following the 'Authentication from scratch' railscast but cannot get it to work.
Controller:
class UsersController < ApplicationController
def new
#user = User.new
end
def create
#user = User.new(params[:user])
if #user.save
redirect_to products_path, notice: 'User created successfully'
else
render 'new'
end
end
end
Model:
class User < ActiveRecord::Base
has_secure_password
attr_accessible :email, :password, :password_confirmation
validates_uniqueness_of :email
end
users#new form:
<h1>Sign up form</h1>
<%= form_for #user do |f| %>
<%= f.label :email %>
<%= f.text_field :email %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.label :password_confirmation %>
<%= f.password_field :password_confirmation %>
<%= f.submit %>
<% end %>
When I try to go to the new user form it throws up a NoMethodError - undefined method 'email' referring to the line that has 'f.text_field :email'.
What am I missing here?
Thanks any help appreciated.
Your users table does not have an email column. Please run a migration to add the column to your users table.

Resources