I have a form that has a few fields that should populate to my database which it doesn't. I am unsure why this is. I defined the parameters which fixed another error but my data is not being stored. My table name is users.
My controller:
Class LandlordPageController < ApplicationController
before_action :get_user
def get_user
#user = current_User
end
def index
end
def show
end
def create
#user = User.new(user_params)
#user.save
redirect_to profile_page_index_path
end
private
def user_params
params.require(:user).permit(:address, :cityResiding, :ssn, :birthDate, :gender, :phoneNumber)
end
end
My form:
<%= form_for :user do |f| %>
<div class="field">
<%=f.label :address, 'Current Address' %><br/>
<%= f.text_field :address, :required => 'required' %>
</div>
<div class="field">
<%=f.label :cityResiding, 'Current City' %><br/>
<%= f.text_field :cityResiding, :required => 'required' %>
</div>
<div class="field">
<%=f.label :phoneNumber, 'Phone Number'%><br/>
<%= f.telephone_field :phoneNumber, maxlength: 15, :required => 'required' %>
</div>
<div class="field">
<%=f.label :gender, 'Gender'%><br/>
<%= f.select :gender, ['',' Male', 'Female', 'Other','Prefer Not to Answer']%>
</div>
<div class="field">
<%=f.label :birthDate, 'Birth Date'%><br/>
<%= f.date_select :birthDate, order: [:month, :day, :year], :required => 'required'%>
</div>
<div class="field">
<%=f.label :ssn, 'Social Security Number' %><br/>
<%= f.text_field :ssn, maxlength: 9 %>
</div>
<div class="actions">
<%= f.submit "Submit Information" %>
</div>
<% end %>
log:
Started GET "/landlord_page" for 127.0.0.1 at 2016-11-06 17:59:58 -0500
Processing by LandlordPageController#index as HTML
User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 1], ["LIMIT", 1]]
Rendering landlord_page/index.html.erb within layouts/application
Rendered landlord_page/index.html.erb within layouts/application (4.0ms)
Rendered layouts/_navbar.html.erb (1.0ms)
Completed 200 OK in 98ms (Views: 88.4ms | ActiveRecord: 0.0ms)
Started POST "/landlord_page" for 127.0.0.1 at 2016-11-06 18:00:06 -0500
Processing by LandlordPageController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"98tUidqprFyTG8ZC/tV9TRDIVlV0I+ocnQfKTUDqorlS+JMFHtaCWz69EwBvH5MrHhnRbg93m695//Z1I5xt3A==", "user"=>{"address"=>"1", "cityResiding"=>"1", "phoneNumber"=>"1", "gender"=>" Male", "birthDate(2i)"=>"11", "birthDate(3i)"=>"6", "birthDate(1i)"=>"2016", "ssn"=>""}, "commit"=>"Submit Information"}
User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 1], ["LIMIT", 1]]
(0.0ms) begin transaction
(0.0ms) rollback transaction
Redirected to http://localhost:3000/profile_page
Completed 302 Found in 4ms (ActiveRecord: 0.0ms)
EDIT: My form does submit data but this error is being thrown on save
NoMethodError in LandlordPageController#create
undefined method `save' for #<Array:0x0000000d883a08>
Instead of new I went with update and removed the save, because the new already executed saving the parameters and save was trying to save nil parameters. I was not creating a new user but meaning to add new parameters to an existing user. This is why the error occured. The full final code is below.
def create
respond_to do |format|
if User.update(user_params)
format.html { redirect_to profile_page_index_path, notice: 'Landlord application successfully submitted.' }
format.json { render :show, status: :created, location: #user }
else
format.html { redirect_to profile_page_index_path, notice: 'Landlord application was not successfully submitted.' }
format.json { render :show, status: :unprocessable_entity }
end
end
end
As has been said, the issue is probably validation errors.
If you mean to update the user, you will need to use the update method instead and pass the user to the form
form_for #user
That will send a PATCH request to the update method on the controller once the form is submitted.
def update
#user.update user_params
if ! #user.valid?
flash[:error] = #user.errors.full_messages
end
redirect_to profile_page_index_path
end
Related
I need a button such that when I click it, the name attribute must be be updated in user table and an address must be saved in address table. address table belongs to user table. Now my error is that when I click submit button i am not able to save the address but my name gets updated in the user table. Can anyone help with it?
Controller Code
class ProfileController < ApplicationController
before_action :set_user, only: %i[index update_profile]
def index; end
def create
#address = Address.new(address_params)
respond_to do |format|
puts'-=-==-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-='
if #address.save
format.html { redirect_to profile_index_path, notice: 'Address was successfully created.' }
else
format.html { render :new }
end
end
end
def update_profile
respond_to do |format|
if #user.update(user_params)
format.html { redirect_to profile_index_path, notice: 'Profile was successfully updated.' }
else
format.html { render :index }
end
end
end
private
def set_user
#user = User.find(current_user.id)
#user.address || #user.build_address
end
def user_params
params.require(:user).permit(:name, address_attributes: %i[area state country])
end
def address_params
params.require(:address).permit(address: %i[area state country])
end
end
Model
address.rb
class Address < ApplicationRecord
belongs_to :user
end
user.rb
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_one :address, dependent: :destroy
validates :name, presence: true
def admin?
true
end
end
View Code
<%= form_for(#user, url: { action: 'update_profile' }, html: { class: 'm-form m-form--fit m-form--label-align-right' } ) do |f| %>
<% if #user.errors.any? %>
<h4><%= pluralize(#user.errors.count, "error") %>
prohibited this profile from being saved:</h4>
<ul>
<% #user.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
<% end %>
<div class="form-group m-form__group row">
<label for="name" class="col-2 col-form-label">
Name
</label>
<div class="col-7">
<%= f.text_field :name, class: 'form-control m-input', placeholder: 'Full Name' %>
</div>
</div>
<div class="m-form__seperator m-form__seperator--dashed m-form__seperator--space-2x"></div>
<%= f.fields_for #user.address do |a| %>
<div class="form-group m-form__group row">
<label for="example-text-input" class="col-2 col-form-label">
Address
</label>
<div class="col-7">
<%= a.text_field :area, class: 'form-control m-input', placeholder: 'Address' %>
</div>
</div>
<div class="form-group m-form__group row">
<label for="example-text-input" class="col-2 col-form-label">
City
</label>
<div class="col-7">
<%= a.text_field :city, class: 'form-control m-input', placeholder: 'City' %>
</div>
</div>
<div class="form-group m-form__group row">
<label for="example-text-input" class="col-2 col-form-label">
State
</label>
<div class="col-7">
<%= a.text_field :state, class: 'form-control m-input', placeholder: 'State' %>
</div>
</div>
<% end %>
<%= f.submit 'Save Changes', class: 'btn btn-accent m-btn m-btn--air m-btn--custom' %>
<%= link_to 'Back', root_path, class: 'btn btn-secondary m-btn m-btn--air m-btn--custom' %>
routes.rb
resources :profile do
collection do
patch 'update_profile'
get 'update_profile'
end
end
Terminal log
Started PATCH "/profile/update_profile" for 127.0.0.1 at 2018-05-07 12:33:15 +0530
Processing by ProfileController#update_profile as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"AJZaELC5GwhOsBCKRZMQMpKySMxNpIIHgNpFBuS1KbBFSs61ByG7RAxVXV8Rd7QXaQ7Htzgyty4Z1uclocXOhQ==", "user"=>{"name"=>"Karthi", "email"=>"suriya#gmail.com", "address"=>{"area"=>"L1, 54th St. & 9th Ave. Ashok Nagar", "city"=>"Chennai", "state"=>"Tamil Nadu", "country"=>"India", "postcode"=>"600083"}}, "commit"=>"Save Changes"}
User Load (0.3ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 7 ORDER BY `users`.`id` ASC LIMIT 1
User Load (0.3ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 7 LIMIT 1
Address Load (0.3ms) SELECT `addresses`.* FROM `addresses` WHERE `addresses`.`user_id` = 7 LIMIT 1
Unpermitted parameter: :address
(0.1ms) BEGIN
(0.2ms) COMMIT
Redirected to http://localhost:3000/profile
Completed 302 Found in 7ms (ActiveRecord: 1.2ms)
Started GET "/profile" for 127.0.0.1 at 2018-05-07 12:33:15 +0530
Processing by ProfileController#index as HTML
User Load (0.3ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 7 ORDER BY `users`.`id` ASC LIMIT 1
User Load (0.2ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 7 LIMIT 1
Address Load (0.2ms) SELECT `addresses`.* FROM `addresses` WHERE `addresses`.`user_id` = 7 LIMIT 1
Rendering profile/index.html.erb within layouts/application
Rendered profile/_profile_card.html.erb (0.3ms)
Rendered profile/_profile_detail.html.erb (1.7ms)
Rendered profile/index.html.erb within layouts/application (3.4ms)
Rendered layouts/_web_font.html.erb (0.3ms)
Rendered layouts/_google_analytics.html.erb (0.2ms)
Rendered layouts/_header.html.erb (1.8ms)
Rendered layouts/_alerts.html.erb (0.4ms)
Completed 200 OK in 32ms (Views: 28.7ms | ActiveRecord: 0.7ms)
I have omitted a few methods unrelated to the error and made some changes to the controller:
class ProfileController < ApplicationController
def create
#address = Address.new(address_params)
respond_to do |format|
if #address.save
format.html { redirect_to profile_index_path, notice: 'Address was successfully created.' }
else
format.html { render :new }
end
end
end
def update_profile
respond_to do |format|
if #user.update(user_params)
format.html { redirect_to profile_index_path, notice: 'Profile was successfully updated.' }
else
format.html { render :index }
end
end
end
private
def user_params
# changed `address_attributes` to `address` as the params in request contains key `address`
params.require(:user).permit(:name, address: %i[area state country])
end
def address_params
# permit the attributes directly instead of nesting them under another `address` key
params.require(:address).permit(*%i[area state country])
end
end
Let me know if it doesn't work.
Please add below line in your user model
user.rb
accepts_nested_attributes_for :address
I think there must be something simple that I'm not setting up correctly, but I cannot figure out this behavior. The user submits and edit form, rails log shows the change is committed, but when I load the record again, it's still the same.
Here's the form
<%= form_for(#deal) do |f| %>
<div class="deal-<%= #deal.id %>">
<div class="field">
<%= f.label :headline %><br />
<%= f.text_field :headline, required: true %>
</div>
<div class="field">
<%= f.label :matter %>
<%= f.text_field :matter %>
</div>
<div class="field">
<%= f.label :summary %>
<%= f.text_area :summary %>
</div>
<%= f.submit "Update" %>
</div>
<% end %>
and relevant parts of controller
def edit
#deal = Deal.find(params[:id])
end
def update
#deal = Deal.find(params[:id])
if #deal.save
flash[:success] = 'Your deal was updated'
redirect_to root_path
else
render 'edit'
end
end
And the output on submit
Started PATCH "/deals/1" for ::1 at 2017-03-21 13:15:17 +0100
Processing by DealsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"Rctg6qcVMfOutyXjZihiR5+zhagr+cduNfA6TSYqOHmjvh+dcQl9TZ/MxZbY+IMyt0LU2PQrsyCjcUJczGcTKg==", "deal"=>{"headline"=>"testheadline", "matter"=>"matter", "summary"=>"First test summary"}, "commit"=>"Update", "id"=>"1"}
Deal Load (0.1ms) SELECT "deals".* FROM "deals" WHERE "deals"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
(0.0ms) begin transaction
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 6], ["LIMIT", 1]]
(0.1ms) commit transaction
Redirected to http://localhost:3000/
Completed 302 Found in 5ms (ActiveRecord: 0.4ms)
def update
#deal = Deal.find(params[:id])
if #deal.update(deal_params)
flash[:success] = 'Your deal was updated'
redirect_to root_path
else
render 'edit'
end
end
private
def deal_params
params.require(:deal).permit(:headline, :matter, :summary)
end
I am trying to nest a user to an account and allow the user to be created when the account is created. I am having an issue when creating both the account and user from the same form, and my server output is not very helpful in trying to isolate the problem.
here is the output when I try to save the Account and User.
Started POST "/accounts" for ::1 at 2016-10-10 20:55:23 -0600
Processing by AccountsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"UK7h4edNzRomi7JGomoZD1ayYmlNxI/h2ZH+NEaJxWQzcFsYAJujr5EDDS2HeprAX41IuS5/crRxmXYz80YpYw==", "account"=>{"subdomain"=>"mydomain", "owner_attributes"=>{"email"=>"swilson#ta#####td.com", "f_name"=>"S####", "l_name"=>"W####", "date_of_birth"=>"19##-##-##", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}}, "commit"=>"Create Account"}
(0.3ms) BEGIN
User Exists (0.3ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = $1 LIMIT $2 [["email", "swilson#ta#####td.com"], ["LIMIT", 1]]
Account Exists (0.3ms) SELECT 1 AS one FROM "accounts" WHERE "accounts"."subdomain" IS NULL LIMIT $1 [["LIMIT", 1]]
(0.2ms) ROLLBACK
Rendering accounts/new.html.erb within layouts/application
Rendered accounts/_form.html.erb (3.8ms)
Rendered accounts/new.html.erb within layouts/application (5.1ms)
Rendered shared/_signed_out_nav.html.erb (1.3ms)
Completed 200 OK in 183ms (Views: 44.2ms | ActiveRecord: 1.1ms)
I believe the issue may have something to do with the account generation and the subdomain. but I Can not pin it down for the life of me!
also I commented out my personal info with the ####...
here is my account controller
class AccountsController < ApplicationController
def new
#account = Account.new
#account.build_owner
end
def create
#account = Account.new(account_params)
respond_to do |format|
if #account.save
format.html {redirect_to root_path, notice: 'Account successfully created.'}
else
format.html {render :new, alert: 'There was a problem, please try again.'}
end
end
end
private
def account_params
params.require(:account).permit(:subdomain, owner_attributes: [:email, :password, :password_confirmation, :f_name, :l_name, :date_of_birth])
end
def set_account
#account = Account.find(params[:id])
end
end
here is my account form:
<%= bootstrap_form_for(#account) do |f| %>
<div class="row">
<div class="col-xs-12">
<%= f.text_field :subdomain, hide_label: true, placeholder: 'Company Name', append: ".patrolvault.net" %>
</div>
</div>
<%= f.fields_for :owner do |o| %>
<div class="row">
<div class="col-xs-12">
<%= o.email_field :email, label: 'Email Address' %>
</div>
<div class="col-xs-12">
<%= o.text_field :f_name, label: 'First Name' %>
</div>
<div class="col-xs-12">
<%= o.text_field :l_name, label: 'Last Name' %>
</div>
<div class="col-xs-12">
<%= o.date_field :date_of_birth, label: 'Date Of Birth' %>
</div>
<div class="col-xs-6">
<%= o.password_field :password, label: 'Password' %>
</div>
<div class="col-xs-6">
<%= o.password_field :password_confirmation, label: 'Confirm Password' %>
</div>
</div>
<% end %>
<%= f.submit :class => 'btn btn-primary' %>
<% end %>
and here is my account model:
class Account < ApplicationRecord
# Before Actions
before_validation :downcase_subdomain
# Relationships
belongs_to :owner, class_name: 'User', optional: true
accepts_nested_attributes_for :owner
# Validations
validates :owner, presence: true
RESTRICTED_SUBDOMAINS = %w(www, patrolvault, test)
validates :subdomain, presence: true,
uniqueness: { case_sensitive: false },
format: { with: /\A[\w\-]+\Z/i, message: 'Contains invalid characters.' },
exclusion: { in: RESTRICTED_SUBDOMAINS, message: 'Restricted domain name'}
# Custom Methods
private
def downcase_subdomain
self.subdomain = subdomain.try(:subdomain)
end
end
Please let me know if you require further info or if I have missed something! Thanks!
so the problem was in my before_validation :downcase_subdomain. once I removed that and the matching method everything began to work fine. I will rework this.
Thanks.
I have a Rails app that builds both a User and an Organization when the first User signs up (User belongs_to Organization). This works fine, and if you fail to put in e.g. the email address (or use an incorrect one) then the form renders the relevant rails error messages just fine. I have additional logic that ensures the first User to sign up an Organization becomes the Admin User of that Organization, and they are permitted to add other users to the site too. If you try and sign up with an existing Organization name it's not permitted.
My tests are all fine, and I'm using the skeleton logic for authentication and authorization provided by the Hartl tutorial (not the new draft one). What I recently noticed was that when an Admin User inputs a blank form for a new user, the app returns to the Organization page and displays a success message. No User object is built (so some part of the app is still working) - I just don't want this to happen (I want the error messages displayed). I can't quite work out what is happening here - why wouldn't the "validates" statements return the errors in this case? Anyway - here's my code:
User.rb:
class User < ActiveRecord::Base
belongs_to :organization
has_many :sales_opportunities
before_save { self.email = email.downcase }
before_destroy :allocate_sales_opportunities_to_admin
before_create :create_remember_token
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-]+(?:\.[a-z\d\-]+)*\.[a-z]+\z/i
validates :email, presence: true, format: { with: VALID_EMAIL_REGEX }, uniqueness: { case_sensitive: false }
has_secure_password
validates :password, length: { minimum: 6 }
validates :organization, presence: true
Organization.rb:
class Organization < ActiveRecord::Base
validates :organization_name, presence: true, length: { maximum: 50 }, uniqueness: true
has_many :users, :inverse_of => :organization, dependent: :destroy
has_many :companies, :inverse_of => :organization, dependent: :destroy
has_many :products, :inverse_of => :organization, dependent: :destroy
has_many :competitors, :inverse_of => :organization, dependent: :destroy
accepts_nested_attributes_for :users
after_create :set_admin
def users_for_form
collection = users.where(organization_id: id)
collection.any? ? collection : users.build
end
private
def set_admin
if self.users.count == 1
self.users.first.update_attribute(:admin, true)
else
return true
end
end
end
Users controller:
class UsersController < ApplicationController
before_action :signed_in_user, only: [:index, :edit, :update]
before_action :correct_user, only: [:edit, :update, :show]
before_action :admin_user, only: :destroy
def update
if #user.update_attributes(user_params)
flash[:success] = "Profile updated"
redirect_to #user
else
render 'edit'
end
end
def create
if signed_in?
#organization = Organization.find(params[:organization_id])
#organization.users.create(user_params)
flash[:success] = "You added a new user to your organization. Send them their login details today!"
redirect_to #organization
else
#user = User.new(user_params)
if #user.save
sign_in #user
flash[:success] = "Thanks for signing up with My App! This is your profile page, be sure to take a look at the support link in the footer"
redirect_to #user
else
render 'new'
end
end
end
private
def user_params
params.require(:user).permit(:name, :email, :password, :password_confirmation, organization_attributes: [:organization_name, :organization_id])
end
#before filters
def signed_in_user
unless signed_in?
store_location
redirect_to signin_url, notice: "Please sign in." unless signed_in?
end
end
def admin_user
redirect_to(root_url) unless current_user.admin?
end
def correct_user
#user = User.find(params[:id])
#organization = #user.organization
redirect_to root_url, notice: "You are not permitted to visit that page. Please create an account or sign in" unless current_user?(#user) || #user.organization == current_user.organization
end
end
Organization's controller:
class OrganizationsController < ApplicationController
before_action :signed_in_user, only: [:edit, :update, :show]
before_action :correct_org, only: [:edit, :update, :show]
def new
#organization = Organization.new
#organization.users.build
end
def create
#organization = Organization.new(organization_params)
if #organization.save
#user = #organization.users.first
sign_in #user
flash[:success] = "Thanks for signing up with My App! This is your profile page, be sure to take a look at the support link in the footer"
redirect_to #user
else
render 'new'
end
end
I'm sure I've got some ugly code in here (the Organizations and Users features were the first new functionality I built when learning RoR and deviating from the Hartl course), and I can't quite work out why the validations are working (no User object is created) when the error message handling is not. For completeness here's the add user form:
<% provide(:title, 'Add more users to your organization') %>
<div class-"container-fluid">
<h1>Sign up colleagues using the form below:</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<div class="well">
<%= form_for([:organization, #user], :html => {:class => "form-horizontal"}) do |f| %>
<%= render 'shared/error_messages' %>
<div class="form-group">
<%= f.label :name, :class => "col-md-4 control-label" %>
<div class ="col-md-8">
<%= f.text_field :name, :placeholder => "What's their name?" %>
</div>
</div>
<div class="form-group">
<%= f.label :email, :class => "col-md-4 control-label" %>
<div class ="col-md-8">
<%= f.text_field :email, :placeholder => "Enter their email address" %>
</div>
</div>
<div class="form-group">
<%= f.label :password, :class => "col-md-4 control-label" %>
<div class ="col-md-8">
<%= f.password_field :password, :placeholder => "Provide a password" %>
</div>
</div>
<div class="form-group">
<%= f.label :password_confirmation, "Repeat Password", :class => "col-md-4 control-label" %>
<div class ="col-md-8">
<%= f.password_field :password_confirmation, :placeholder => "Repeat password" %>
</div>
</div>
<%= f.submit "Add new user account", class: "btn btn-large btn-success" %>
<% end %>
</div>
</div>
</div>
</div>
Here's the working form for a new Organization/User combo:
<% provide(:title, 'Sign up') %>
<div class="container-fluid">
<h1>Sign up!</h1>
<div class="row">
<div class="col-md-8 col-md-offset-2">
</div>
</div>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<div class="well">
<%= form_for(#organization, :html => {:class => "form-horizontal"}) do |f| %>
<%= render 'shared/org_error_messages' %>
<div class="form-group">
<%= f.label :organization_name, :class => "col-md-4 control-label" %>
<div class ="col-md-8">
<%= f.text_field :organization_name, :placeholder => "Who do you work for?" %>
</div>
</div>
<%= f.fields_for :users, #organization.users_for_form do |user| %>
<div class="form-group">
<%= user.label :name, :class => "col-md-4 control-label" %>
<div class ="col-md-8">
<%= user.text_field :name, :placeholder => "What's your name?" %>
</div>
</div>
<div class="form-group">
<%= user.label :email, :class => "col-md-4 control-label" %>
<div class ="col-md-8">
<%= user.text_field :email, :placeholder => "Email" %>
</div>
</div>
<div class="form-group">
<%= user.label :password, :class => "col-md-4 control-label" %>
<div class ="col-md-8">
<%= user.password_field :password, :placeholder => "Enter password - minimum 6 characters" %>
</div>
</div>
<div class="form-group">
<%= user.label :password_confirmation, "Repeat Password", :class => "col-md-4 control-label" %>
<div class ="col-md-8">
<%= user.password_field :password_confirmation, :placeholder => "Repeat password" %>
</div>
</div>
<%= user.hidden_field :organization_id, input_html: {value: #organization.id} %>
<% end %>
<%= f.submit "Create my account", class: "btn btn-large btn-success" %>
<% end %>
</div>
</div>
</div>
<div>
Where am I going wrong?
EDIT - here is the log from my console when the above happens:
Processing by UsersController#new as HTML
Parameters: {"organization_id"=>"1"}
Rendered shared/_error_messages.html.erb (0.1ms)
Rendered users/new.html.erb within layouts/application (3.4ms)
Rendered layouts/_shim.html.erb (0.0ms)
User Load (0.6ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = 'b8cabbe1e1514f14be24f95d48248ad716e11342' LIMIT 1
Organization Load (0.3ms) SELECT "organizations".* FROM "organizations" WHERE "organizations"."id" = $1 LIMIT 1 [["id", 1]]
Rendered layouts/_header.html.erb (3.9ms)
Rendered layouts/_footer.html.erb (0.2ms)
Completed 200 OK in 28ms (Views: 26.0ms | ActiveRecord: 0.9ms)
Started POST "/organizations/1/users" for 127.0.0.1 at 2014-10-05 22:22:15 +0630
Processing by UsersController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"fKx7bdWtC7bmBKMRF3ivwBlmJXzrcWJ16dYYOfNLBC0=", "user"=>{"name"=>"", "email"=>"", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Add new user account", "organization_id"=>"1"}
User Load (0.6ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = 'b8cabbe1e1514f14be24f95d48248ad716e11342' LIMIT 1
Organization Load (0.4ms) SELECT "organizations".* FROM "organizations" WHERE "organizations"."id" = $1 LIMIT 1 [["id", 1]]
(0.3ms) BEGIN
User Exists (0.5ms) SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER('') LIMIT 1
(0.8ms) COMMIT
Redirected to http://0.0.0.0:3000/organizations/1
Completed 302 Found in 14ms (ActiveRecord: 2.7ms)
Started GET "/organizations/1" for 127.0.0.1 at 2014-10-05 22:22:15 +0630
Processing by OrganizationsController#show as HTML
Parameters: {"id"=>"1"}
User Load (0.6ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = 'b8cabbe1e1514f14be24f95d48248ad716e11342' LIMIT 1
Organization Load (0.4ms) SELECT "organizations".* FROM "organizations" WHERE "organizations"."id" = $1 LIMIT 1 [["id", 1]]
CACHE (0.0ms) SELECT "organizations".* FROM "organizations" WHERE "organizations"."id" = $1 LIMIT 1 [["id", "1"]]
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."organization_id" = $1 [["organization_id", 1]]
Rendered organizations/_users_index.html.erb (1.0ms)
Organization Load (0.4ms) SELECT "organizations".* FROM "organizations" WHERE "organizations"."id" = $1 LIMIT 1 [["id", 1]]
Company Load (0.6ms) SELECT "companies".* FROM "companies" WHERE "companies"."organization_id" = $1 [["organization_id", 1]]
Competitor Load (0.4ms) SELECT "competitors".* FROM "competitors" WHERE "competitors"."organization_id" = $1 [["organization_id", 1]]
Product Load (0.4ms) SELECT "products".* FROM "products" WHERE "products"."organization_id" = $1 [["organization_id", 1]]
Rendered organizations/show.html.erb within layouts/application (13.3ms)
Rendered layouts/_shim.html.erb (0.0ms)
Rendered layouts/_header.html.erb (0.6ms)
Rendered layouts/_footer.html.erb (0.2ms)
Completed 200 OK in 37ms (Views: 30.6ms | ActiveRecord: 3.1ms)
I think it's something to do with the way I'm handling creating a new user, after further testing. The following code is almost certainly where the error lies:
def create
if signed_in?
#organization = Organization.find(params[:organization_id])
#organization.users.create(user_params)
flash[:success] = "You added a new user to your organization. Send them their login details today!"
redirect_to #organization
else
#user = User.new(user_params)
if #user.save
sign_in #user
flash[:success] = "Thanks for signing up with My App! This is your profile page, be sure to take a look at the support link in the footer"
redirect_to #user
else
render 'new'
end
end
end
Where I'm testing if the User is signed in, the choice either leads to adding a new user to the current organization or creating both from scratch. What I need is a way to test whether #organization.users.create was successful (or maybe I need #organization.users.new) and if it fails the validations then I need to render "users/new" rather than heading back to the #organization path and displaying the (obviously incorrect) flash that a new user has been created.
Anyone got any ideas how I test for this? I tried a quick if/else test (along the lines of "if #organization.users.create ... else: render the users/new page"), but then I got a bunch of form errors because I wasn't defining the object that the page was creating.
I solved this with the change to the create function in the Users controller - I was creating a new #organization.user regardless of the error messages in the form. Instead I needed to use #user = #organization.users.new, and then use the same if #user.save ... test that works for a new user. See the below code for how it was fixed:
def create
if signed_in?
#organization = Organization.find(params[:organization_id])
#user = #organization.users.new(user_params)
if #user.save
flash[:success] = "You added a new user to your organization. Send them their login details today!"
redirect_to #organization
else
render 'new'
end
else
#user = User.new(user_params)
if #user.save
sign_in #user
flash[:success] = "Thanks for signing up with My App! This is your profile page, be sure to take a look at the support link in the footer"
redirect_to #user
else
render 'new'
end
end
end
On the account settings page for my Rails app I am trying to use Ajax to have the displayed users settings info updated after the update form is submitted. Right now when I submit the form the database gets updated and the _account_settings.html.erb partial appears to get re-rendered, but the partial doesn't show the updated information. For example, say the users name is "John Doe" and he clicks the '#edit_name' link. This renders the _name_form.html.erb which he can use to change his name. When he changes his name and submits the form, let's say he changes it to "Joe Blow", the form disappears and the 'Name: <%= current_user.name %> - click to edit' shows up again but the name is still "John Doe" even though the name in the DB is now "Joe Blow". If I refresh the page the name now appears as "Joe Blow". I am using devise and made a custom registrations controller to allow the user to update certain attributes without entering a password (name still requires the current password). I used this code provided by the devise and simply added
respond_to do |format|
format.html { redirect_to edit_user_registration_path }
format.js
end
to the end of the 'if #user.update_attributes(account_update_params)' block in the above link. Any ideas as to why the re-rendered partial isn't showing the updated user information?
edit.html.erb
<h1>Account Settings</h1>
<div id="account_settings_container">
<%= render 'account_settings' %>
</div>
_account_settings.html.erb
<div class="user-attribute-container">
<%= link_to "#", class: "edit-attribute", id: "edit_name", remote: true do %>
<p>Name: <%= current_user.name %> - click to edit</p>
<% end %>
</div>
<div class="user-attribute-container">
<%= link_to "#", class: "edit-attribute", id: "edit_email", remote: true do %>
<p>Email: <%= current_user.email %> - click to edit</p>
<% end %>
</div>
<div class="user-attribute-container">
<%= link_to "#", class: "edit-attribute", id: "edit_password", remote: true do %>
<p>Password: click to edit your password</p>
<% end %>
</div>
<%= javascript_tag do %>
$("#edit_name").click(function() {
$(this).hide().after("<%= escape_javascript(render('name_form')) %>");
});
$("#edit_email").click(function() {
$(this).hide().after("<%= escape_javascript(render('email_form')) %>");
});
$("#edit_password").click(function() {
$(this).hide().after("<%= escape_javascript(render('password_form')) %>");
});
<% end %>
_name_form.html.erb (the email and password form partials have :email, :password & :password_confirmation instead of :name, otherwise they're the same)
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :method => :put, :html => { id: "edit_user_name" }, remote: true) do |f| %>
<%= f.label :name, "Name" %>
<%= f.text_field :name %>
<%= f.label :password_field, "Password" %>
<%= f.password_field :current_password %>
<%= f.submit "Update" %>
<% end %>
update.js.erb
$("#account_settings_container").html("<%= escape_javascript(render('account_settings')) %>");
From the log file:
Started PUT "/users" for 127.0.0.1 at 2014-06-09 15:01:21 -0700<br>
Processing by RegistrationsController#update as JS<br>
Parameters: {"utf8"=>"✓", "user"=>{"name"=>"Joe Blow", "current_password"=>"[FILTERED]"}, "commit"=>"Update"}<br>
[1m[36mUser Load (0.0ms)[0m [1mSELECT "users".* FROM "users" WHERE "users"."id" = 14 ORDER BY "users"."id" ASC LIMIT 1[0m<br>
[1m[35mUser Load (0.0ms)[0m SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 14]]<br>
[1m[36m (0.0ms)[0m [1mBEGIN[0m<br>
[1m[35mSQL (0.0ms)[0m UPDATE "users" SET "name" = $1, "updated_at" = $2 WHERE "users"."id" = 14 [["name", "Joe Blow"], ["updated_at", Mon, 09 Jun 2014 15:01:21 PDT -07:00]]<br>
[1m[36m (0.0ms)[0m [1mCOMMIT[0m<br>
Rendered registrations/_name_form.html.erb (15.6ms)<br>
Rendered registrations/_email_form.html.erb (0.0ms)<br>
Rendered registrations/_password_form.html.erb (15.6ms)<br>
Rendered registrations/_account_settings.html.erb (46.9ms)<br>
Rendered registrations/update.js.erb (46.9ms)<br>
Completed 200 OK in 219ms (Views: 78.1ms | ActiveRecord: 0.0ms)
Custom devise registrations controller:
class RegistrationsController < Devise::RegistrationsController
def update
#user = User.find(current_user.id)
successfully_updated = if needs_password?(#user, params)
#user.update_with_password(devise_parameter_sanitizer.sanitize(:account_update))
else
# remove the virtual current_password attribute
# update_without_password doesn't know how to ignore it
params[:user].delete(:current_password)
#user.update_without_password(devise_parameter_sanitizer.sanitize(:account_update))
end
if successfully_updated
# sign_in #user, :bypass => true
respond_to do |format|
format.html { redirect_to edit_user_registration_path }
format.js
end
else
respond_to do |format|
format.html { render "edit" }
format.js
end
end
end
private
def needs_password?(user, params)
user.email != params[:user][:email] || params[:user][:password].present? || user.name != params[:user][:name]
end
end
current_user is generated by Devise using a before_filter. So the object returned, will be the user as it was before that action method was called. You need to use the #user object which is the user object that is modified by the action method.
So for example:
<p>Name: <%= #user.name %> - click to edit</p>