Good day,
I have a devise users model and in edit user page I want to add a custom field called "add verification documents" which takes in multiple documents(pdf's) that are uploaded in edit user page. A User can upload multiple documents.
# user.rb
class User < ActiveRecord::Base
has_many :verification_documents
end
# routes.rb
devise_for :users,
path: '',
path_names: {sign_in: 'login', sign_out: 'logout',sign_up: 'sign-up', edit: 'profile'},
controllers: {
omniauth_callbacks: 'omniauth_callbacks',
registrations: 'registrations'
}
My Requirement is similar to
Rails Devise - Register User with Associated Model ,
But Instead of address attributes, here I want to upload multiple verification verification documents to the verification_documents model during update action of the devise user model.
# views/devise/registrations/edit.html.erb
<div class="row">
<%= form_for(resource, as: resource_name,
url: registration_path(resource_name),
html: { method: :put },
multipart: true) do |f| %>
<div class="form-group">
<%= f.text_field :fullname, autofocus: true,
placeholder: "Full Name *", class: "form-control" %>
</div>
<div class="form-group">
<%= f.email_field :email, placeholder: "Email *",
class: "form-control" %>
</div>
<span class="btn btn-default btn-file btn-green pad_small">
Upload Verification Documents
<input type="file" accept="application/pdf" name="input-file-preview"/>
<%= file_field_tag "verification_documents[]", type: :file, multiple: true %>
</span>
<div class="actions">
<%= f.button "Save", class: "btn btn-green pad_small" %>
</div>
</div>
# verification_document.rb
class VerificationDocument < ActiveRecord::Base
belongs_to :user
has_attached_file :verification_documents
validates_attachment_content_type :verification_documents,
{ :content_type => %w( application/pdf ) }
end
Is it possible to update something like below in RegistrationsController as ?
# RegistrationsController < Devise::RegistrationsController
def update
if #user.update(user_params)
if params[:verification_documents]
params[:verification_documents].each do |doc|
#user.verification_documents.create(verification_documents: doc)
end
end
redirect_to root_path, notice: "Updated..."
else
render :edit
end
end
In application_controller.rb I have,
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up,
keys: [:fullname, :subscribe])
devise_parameter_sanitizer.permit(:account_update,
keys: [:fullname, :reset_password_token, :verification_documents])
end
Any Help is Highly Appreciated.Thanks in Advance!
UPDATE 1
I have added this to the Registrations Controller
def update
super
#user = User.find(current_user.id)
if params[:user][:verification_documents]
params[:user][:verification_documents].each do |doc|
#user.verification_documents.create(verification_documents: doc)
end
puts "document saved"
else
puts "not saved"
end
end
I tried to change the user phone number and upload the verification_documents (pdf's) in the users edit page.The values of devise user model Attribute's were successfully updated(The phone number is an attribute of user model).But the values for the verification_document model attributes are not saved.
phone number is updated but the verification_documents were still not saved
Log:
Processing by RegistrationsController#update as HTML
Parameters: {"utf8"=>"▒~\~S", "authenticity_token"=>"Xic+IFWWdzK4KaFzgnVzsOjMDPDaznJBjosj69khn3AfhrJr0mWsJrobK/mWHWiaANFqQAKj7wUPRYslfJZoPw==", "user"=>{"fullname"=>"Mohan Krishna Gangarapu", "email"=>"mohankrish93#gmail.com", "alternate_email"=>"", "business_name"=>"", "location"=>"", "phone_number"=>"9999999999", "alternate_phone_number"=>"", "dealer"=>"0", "fleet_manager"=>"0", "description"=>"", "url"=>"", "current_password"=>"[FILTERED]", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "deactivate"=>"false"}, "verification_documents"=>[#<ActionDispatch::Http::UploadedFile:0x007f1412365420 #tempfile=#<Tempfile:/tmp/RackMultipart20170411-23997-11lrzwz.pdf>, #original_filename="pdf-test.pdf", #content_type="application/pdf", #headers="Content-Disposition: form-data; name=\"verification_documents[]\"; filename=\"pdf-test.pdf\"\r\nContent-Type: application/pdf\r\n">, #<ActionDispatch::Http::UploadedFile:0x007f14123653f8 #tempfile=#<Tempfile:/tmp/RackMultipart20170411-23997-e1grsp.pdf>, #original_filename="pdfurl-guide.pdf.pdf", #content_type="application/pdf", #headers="Content-Disposition: form-data; name=\"verification_documents[]\"; filename=\"pdfurl-guide.pdf.pdf\"\r\nContent-Type: application/pdf\r\n">], "button"=>""}
^[[1m^[[36mUser Load (0.2ms)^[[0m ^[[1mSELECT `users`.* FROM `users` WHERE `users`.`id` = ? ORDER BY `users`.`id` ASC LIMIT 1^[[0m [["id", 686]]
^[[1m^[[35mUser Load (0.4ms)^[[0m SELECT `users`.* FROM `users` WHERE `users`.`id` = ? LIMIT 1 [["id", 686]]
Unpermitted parameters: business_name, location
^[[1m^[[36mSQL (0.1ms)^[[0m ^[[1mBEGIN^[[0m
^[[1m^[[35mSQL (0.3ms)^[[0m UPDATE `users` SET `phone_number` = ?, `deactivate` = ?, `updated_at` = ? WHERE `users`.`id` = ? [["phone_number", "9999999999"], ["deactivate", 0], ["updated_at", "2017-04-11 05:32:57"], ["id", 686]]
^[[1m^[[36m (1.8ms)^[[0m ^[[1mCOMMIT^[[0m
Redirected to http://104.251.212.100:3000/
Completed 302 Found in 17ms (ActiveRecord: 3.6ms)
Started GET "/" for 156.73.67.6 at 2017-04-11 05:32:57 -0500
Cannot render console from 156.73.67.6! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by PagesController#home as HTML
Related
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
This is my views/devise/registrations/edit.html.erb:
<%= simple_form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put, class: "edit-user-form m-t" }) do |f| %>
<%= f.error_notification %>
<div class="form-group">
<%= f.input_field :email, required: true, autofocus: true %>
</div>
<div class="form-group">
<%= f.input_field :current_password, hint: "we need your current password to confirm your changes", placeholder: "current password", required: true %>
</div>
<div class="form-group">
<%= f.input_field :password, autocomplete: "off", hint: "leave it blank if you don't want to change it", placeholder: "new password", required: false %>
</div>
<div class="form-group">
<%= f.input_field :password_confirmation, placeholder: "confirm new password", required: false %>
</div>
<div class="form-group">
<%= f.association :school, collection: School.where(school_type: [:college, :university]), prompt: "Choose a school", class: 'col-lg-4 form-control', label: false %>
</div>
</div>
<div class="form-group">
<div class="col-lg-12 text-center">
<%= f.button :submit, "Update", class: "btn btn-lg edit-account-update-button" %>
</div>
</div>
<% end %>
And this is my ApplicationController:
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_action :configure_permitted_parameters, if: :devise_controller?
check_authorization :unless => :devise_controller?
rescue_from CanCan::AccessDenied do |exception|
respond_to do |format|
format.json { head :forbidden }
format.html { redirect_back(fallback_location: root_path, flash: { danger: exception.message }) }
end
end
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:account_update, keys: [:avatar, :avatar_cache, :remove_avatar, :school_id])
end
end
The issue though is that it isn't updating the record, here is the log from that operation:
Started PUT "/users" for ::1 at 2016-11-02 19:22:59 -0500
Processing by DeviseInvitable::RegistrationsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"Xo445XVpElgDmfcjywZKEbsXIqZR/2Wgw==", "user"=>{"remove_avatar"=>"0", "avatar_cache"=>"", "email"=>"coach#test.com", "current_password"=>"[FILTERED]", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "school_id"=>"3"}, "commit"=>"Update"}
User Load (4.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 7], ["LIMIT", 1]]
User Load (9.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 7], ["LIMIT", 1]]
(0.7ms) BEGIN
SQL (4.2ms) UPDATE "users" SET "updated_at" = $1, "avatar" = $2 WHERE "users"."id" = $3 [["updated_at", 2016-11-03 00:22:59 UTC], ["avatar", "a1.jpg"], ["id", 7]]
(0.8ms) COMMIT
Redirected to http://localhost:3000/
Completed 302 Found in 139ms (ActiveRecord: 19.1ms)
Note that the school_id is set in the params, so we know it properly accepts the input from the form. But the SQL UPDATE statement, doesn't include school_id, so it doesn't actually save that info to the DB.
Also note that there are no unpermitted params messages in the log.
What could be causing this?
Edit 1
This is the School.rb model:
class School < ApplicationRecord
has_many :users
enum school_type: { high_school: 0, college: 1, university: 2 }
end
This is the User.rb model:
class User < ActiveRecord::Base
belongs_to :school
end
The problem was that your devise model User was inheriting ActiveRecord::Base instead of ApplicationRecord which is an abstract class in Rails 5. With the inheritance of latter, most of the gems which deal with models can and do modify the code of ActiveRecord::Base in their own context without affecting other models, which isn't possible if you inherit the former.
Source: Why Rails 5 uses ApplicationRecord instead of ActiveRecord::Base?
The attachment resume seems to works fine, but i do not have any insert into database (null, null, null , null) and i do not have file uploaded to any folder in my app...
class AddAttachmentCvToUsers < ActiveRecord::Migration
def change
change_table :users do |t|
t.attachment :cv
end
end
end
User model :
attr_accessor :cv
validates_attachment :cv
has_attached_file :cv, :path=>":rails_root/storage/#{Rails.env}#{ENV['RAILS_TEST_NUMBER']}/."
I have also installed carrierwave but still no effects..
Edit:
User Controller (I do not have another controller for attachments) :
class UsersController < ApplicationController
def new
#users = User.new
end
def create
#user = User.new(user_params)
if #user.save
session[:user_id] = #user.id
current_user = #user.id
redirect_to '/status'
else
redirect_to '/signup'
end
end
private
def user_params
params.require(:user).permit(:first_name, :last_name, :email, :PESEL, :phone, :password,:cv)
end
end
View for new user with attachement:
<div class="login">
<div class="container">
<div class="form">
<h1>SIGN UP</h1>
<%= form_for #users,:html=> {:multipart=>true} do |f| %>
<%= f.text_field :first_name, :placeholder => "First name" %>
<%= f.text_field :last_name, :placeholder => "Last name" %>
<%= f.email_field :email, :placeholder => "Email" %>
<%= f.text_field :PESEL, :placeholder => "PESEL number" %>
<%= f.phone_field :phone, :placeholder => "Phone Number" %>
<%= f.password_field :password, :placeholder => "Password" %>
<p>CV</p>
<%= f.file_field :cv, name: "CV", class: 'form-control' %>
<%= f.submit "Sign up", class: "btn-submit" %>
<% end %>
</div>
</div>
</div>
Some logs from console:
Started POST "/users" for 127.0.0.1 at 2016-05-18 03:55:17 +0200
Processing by UsersController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"Fw6easThY51CDppDDVfqO0ProQITaltqP3DaIL3An67ey4vGXh2yEerhhhxoo3bTp/mKbkIaAmktzBviBIjg8g==", "user"=>{"first_name"=>"Test", "last_name"=>"Test", "email"=>"test#t.pl", "PESEL"=>"91020300441", "phone"=>"609123123", "password"=>"[FILTERED]"}, "CV"=>#<ActionDispatch::Http::UploadedFile:0x007f25790c1b60 #tempfile=#<Tempfile:/tmp/RackMultipart20160518-26849-rqaabr.pdf>, #original_filename="pdf-test.pdf", #content_type="application/pdf", #headers="Content-Disposition: form-data; name=\"CV\"; filename=\"pdf-test.pdf\"\r\nContent-Type: application/pdf\r\n">, "commit"=>"Sign up"}
(0.1ms) BEGIN
User Exists (1.4ms) SELECT 1 AS one FROM `users` WHERE `users`.`email` = BINARY 'test#t.pl' LIMIT 1
User Exists (0.1ms) SELECT 1 AS one FROM `users` WHERE `users`.`PESEL` = BINARY '91020300441' LIMIT 1
SQL (0.1ms) INSERT INTO `users` (`first_name`, `last_name`, `email`, `PESEL`, `phone`, `password_digest`, `created_at`, `updated_at`) VALUES ('Test', 'Test', 'test#t.pl', '91020300441', '609123123', '$2a$10$HmHAiJkHv1Tada/OpzKXKOISiwumoFKTy48tFpNBYuATq/A5GaC9G', '2016-05-18 01:55:17', '2016-05-18 01:55:17')
SQL (1.0ms) INSERT INTO `job_apps` (`user_id`, `created_at`, `updated_at`) VALUES (35, '2016-05-18 01:55:17', '2016-05-18 01:55:17')
(3.0ms) COMMIT
Redirected to http://localhost:3000/status
Completed 302 Found in 135ms (ActiveRecord: 8.2ms)
Started GET "/status" for 127.0.0.1 at 2016-05-18 03:55:17 +0200
Processing by JobAppsController#index as HTML
You have overridden the name attribute of the file_field, which has broken Rails naming conventions. If you remove the name attribute, Rails will be able to pass the file details uploaded in the :cv field to the database.
Change the file_field to this:
<%= f.file_field :cv, class: 'form-control' %>
If you have Javascript attached to the form, and need to refer to the file_field element, you can use this, instead:
<%= f.file_field :cv, id: "cv", class: "form-control" %>
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
Pretty standard update in my opinion, but upon submitting the put request, the attribute is not updated. Here is my relevant model:
class Vendor < ActiveRecord::Base
geocoded_by :address
after_validation :geocode,
:if => lambda{ |obj| obj.address_changed? }
end
My controller methods:
def edit
#vendor = Vendor.find(params[:id])
end
def update
#vendor = Vendor.find(params[:id])
if #vendor.update_attributes(vendor_params)
redirect_to vendors_mgmt_path
else
render 'edit'
end
end
def vendor_params
params.permit(:id, :name, :address, :image, :latitude, :longituded )
end
I see this in the server log after trying to update:
Started PUT "/vendors/1" for 127.0.0.1 at 2013-10-20 20:44:54 -0700
Processing by VendorsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"fTbZVEfckQz4xQzY5xSMQCArrGZqymNsVeyic/PXKcE=", "vendor"=>{"name"=>"Store", "address"=>"1221 E. Main St."}, "commit"=>"Save changes", "id"=>"1"}
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1
Vendor Load (0.2ms) SELECT "vendors".* FROM "vendors" WHERE "vendors"."id" = ? LIMIT 1 [["id", "1"]]
Unpermitted parameters: utf8, _method, authenticity_token, vendor, commit
(0.1ms) begin transaction
(0.1ms) commit transaction
Redirected to http://localhost:3000/vendors/mgmt
Completed 302 Found in 10ms (ActiveRecord: 0.6ms)
This confuses me, because the Vendor form looks like so, and has no authenticity token etc.
<h1>Update <%= "#{#vendor.name}" %></h1>
<%= form_for(#vendor) do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :address %>
<%= f.text_field :address %>
<%= f.label :Logo %>
<%= f.file_field :image %>
<%= f.submit "Save changes", class: "btn btn-success" %>
<% end %>
Anyone see any glaring errors? Any help is much appreciated. Thanks in advance!
Rails by default includes certain hidden fields in all forms, such as the authenticity_token, which is present to stop CSRF. (More info here) I would recommend changing the line:
params.permit(:id, :name, :address, :image, :latitude, :longituded )
to:
params.require(:vendor).permit(:id, :name, :address, :image, :latitude, :longituded)
Changing this line in your controller should permit the other parameters that are submitted by the form, not just the ones in the vendor param.
Also, you misspelled "longitude", I'm not sure if that's causing any additional trouble or if it's just a typo in your question instead.