Validations on extra column in devise not working - ruby-on-rails

While inserting some thing in firstName field its show error that firstName should not be blank....
Any Suggestion why this will be happening......?
Model
members.rb file
class Member < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
validates :firstName, :presence => true
end
View
new.html.erb file
<h2>Sign up</h2>
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div><%= f.label :firstName %><br />
<%= f.email_field :firstName, :autofocus => true %></div>
<div><%= f.label :email %><br />
<%= f.email_field :email, :autofocus => true %></div>
<div><%= f.label :password %><br />
<%= f.password_field :password %></div>
<div><%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %></div>
<div><%= f.submit "Sign up" %></div>
<% end %>
<%= render "devise/shared/links" %>

In Rails 4, you need to make a list of the parameters you are expecting a form to submit to you. this is called "strong parameters".
Devise has its own way that you can do this, called "sanitizing".
Look up those two terms.
See this answer: https://stackoverflow.com/a/20756469/2308190

Is it possible even you didn't input first name, but in params it still has value as empty string ""? If you use following, could it work?
validates :firstName, length: { minimum: 2 }
You can chage 2 to any other number.

Update your devise view with this.
<h2>Sign up</h2>
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div><%= f.label :firstName %><br />
<%= f.text_field :firstname, :autofocus => true %></div>
<div><%= f.label :email %><br />
<%= f.email_field :email%></div>
<div><%= f.label :password %><br />
<%= f.password_field :password %></div>
<div><%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %></div>
<div><%= f.submit "Sign up" %></div>
<% end %>
<%= render "devise/shared/links" %>
And model
validates :firstname, :presence => true

Related

Avatar (picture) can't be blank after avatar attached and form submitted - carrierwave error

I am a newbie in Rails. I use Rails 4.2 with Ruby 2.0, I've installed the carrierwave gem. I followed the instructions how to setup with devise.
But the validation or the picture does not work correctly, cause I always get the "Avatar can't be blank" error message when I attached a picture and submit the form. I have no idea where is my mistake.
User model:
class User < ActiveRecord::Base
mount_uploader :avatar, AvatarUploader
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable,
:omniauthable, :omniauth_providers => [:facebook, :google_oauth2]
after_initialize :set_default_role, :if => :new_record?
# Validations
validates_presence_of :avatar
validates_integrity_of :avatar
validates_processing_of :avatar
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
user.name = auth.info.nickname
user.email = auth.info.email
user.password = Devise.friendly_token[0,20]
end
end
end
Sign up form
<h2>Sign up</h2>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { multipart: true }) do |f| %>
<%= devise_error_messages! %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name, autofocus: true %>
</div>
<div class="field">
<%= f.label 'Woman' %><br />
<%= f.radio_button :gender, 'Woman' %>
<br>
<%= f.label 'Man' %><br />
<%= f.radio_button :gender, 'Man' %>
</div>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email %>
</div>
<div class="field">
<%= f.label :phone %><br />
<%= f.text_field :phone %>
</div>
<div class="field">
<%= f.label :password %>
<% if #minimum_password_length %>
<em>(<%= #minimum_password_length %> characters minimum)</em>
<% end %><br />
<%= f.password_field :password, autocomplete: "off" %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "off" %>
</div>
<div class="field">
<%= f.label :city %><br />
<%= f.text_field :city %>
</div>
<div class="field">
<%= f.label :county %><br />
<%= f.text_field :county %>
</div>
<div class="field">
<label>My Avatar</label>
<%= f.file_field :avatar %>
<%= f.hidden_field :avatar_cache %>
</div>
<div class="actions">
<%= f.submit "Sign up" %>
</div>
<% end %>
<%= render "users/shared/links" %>
Application controller's strong parameters:
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:email) }
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit({ roles: [] }, :name, :email, :password, :password_confirmation, :avatar, :avatar_cache) }
devise_parameter_sanitizer.for(:account_update) { |u| u.permit({ roles: [] }, :name, :email, :password, :password_confirmation, :avatar, :avatar_cache) }
end
I really do not see where is my mistake. Maybe do you see?
Because you have this validation:
validates_presence_of :avatar
means, you have to upload an avatar.
You will get this error message: Avatar can't be blank if you try to submit the form without attaching the avatar.
So, make sure you attach an avatar before hitting the Sign Up button.

Carrierwave upload image to postgresql table

I am trying to make an upload profile picture option for my form. I am using carrierwave to do so. While I can run the form with no problems, when I upload and save changes (i think), i check my postgres database column and see that the avatar column is still empty. The image has not been saved.
Here is my form:
<h2>Edit <%= resource_name.to_s.humanize %></h2>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put , :multipart => true}) do |f| %>
<%= devise_error_messages! %>
<div><%= f.label :email %><br />
<%= f.email_field :email, autofocus: true %></div>
<% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
<div>Currently waiting confirmation for: <%= resource.unconfirmed_email %></div>
<% end %>
<div><%= f.label :password %> <i>(leave blank if you don't want to change it)</i><br />
<%= f.password_field :password, autocomplete: "off" %></div>
<div><%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "off" %></div>
<div><%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
<%= f.password_field :current_password, autocomplete: "off" %></div>
<!-- add profile picture portion -->
<div><%= f.label :avatar %><br />
<%= f.file_field :avatar %>
<div><%= f.submit "Update" %></div>
<% end %>
Here is my model:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
mount_uploader :avatar, AvatarUploader
end
And here is my uploader:
class AvatarUploader < CarrierWave::Uploader::Base
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
def extension_white_list
%w(jpg jpeg gif png)
end
end

unable to get data from another model using accepts_nested_attributes_for

I have two models User and profile. The profile model has many attributes. I have accessed them in User model using accepts_nested_attributes_for.
Here is my profile.rb model
class Profile < ActiveRecord::Base
attr_accessible :address, :certification, :college, :contact_no, :first_name, :higher_education, :interested_in_learning, :last_name, :profile_pic, :school, :user_id, :would_like_to_teach, :about_video, :about_video_html, :category_name, :category_ids
mount_uploader :profile_pic, ProfimageUploader
has_and_belongs_to_many :categories
belongs_to :user
AutoHtml.add_filter(:image) do |text|
text.gsub(/http:\/\/.+\.(jpg|jpeg|bmp|gif|png)(\?\S+)?/i) do |match|
%|<img src="#{match}" alt=""/>|
end
end
auto_html_for :about_video do
image
youtube(:width => 170, :height => 100)
link :target => "_blank", :rel => "nofollow"
simple_format
end
def self.search(search)
if search
where('first_name LIKE ?', "%#{search}%")
else
find(:all)
end
end
end
Here is my user.rb model
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :omniauthable
has_one :profile, :dependent => :destroy
accepts_nested_attributes_for :profile
# Setup accessible (or protected) attributes for your model
attr_accessible :name, :email, :password, :password_confirmation, :remember_me, :uid, :provider, :profile_attributes
mount_uploader :profile_pic, ProfimageUploader
acts_as_followable
acts_as_follower
def self.find_for_facebook_oauth(auth, signed_in_resource=nil)
user = User.where(:provider => auth.provider, :uid => auth.uid).first
if user
return user
else
registered_user = User.where(:email => auth.info.email).first
if registered_user
return registered_user
else
user = User.create(name:auth.extra.raw_info.name,
provider:auth.provider,
uid:auth.uid,
email:auth.info.email,
password:Devise.friendly_token[0,20],
)
end
end
end
end
The form in my User edit page is
<% resource.build_profile %>
<%= simple_form_for resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put, :multipart => true, :class => ".form-horizontal" } do |f| %>
<%= devise_error_messages! %>
<div><%= f.label :email %><br />
<%= f.email_field :email, :autofocus => true, :readonly => true %></div>
<% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
<div>Currently waiting confirmation for: <%= resource.unconfirmed_email %></div>
<% end %>
<div><%= f.label :password %> <i>(leave blank if you don't want to change it)</i><br />
<%= f.password_field :password, :autocomplete => "off" %></div>
<div><%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %></div>
<div><%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
<%= f.password_field :current_password %></div>
<%= f.fields_for :profile, #user.profile do |prof| %>
<div class="field">
<%= prof.label :first_name %><br />
<%= prof.text_field :first_name %>
</div>
<div class="field">
<%= prof.label :last_name %><br />
<%= prof.text_field :last_name %>
</div>
<div class="field">
<%= prof.label :address %><br />
<%= prof.text_area :address %>
</div>
<div class="field">
<%= prof.label :profile_pic %><br />
<%= prof.file_field :profile_pic %>
</div>
<div class="field">
<%= prof.label :contact_no %><br />
<%= prof.text_field :contact_no %>
</div>
<div class="field">
<%= prof.label :school %><br />
<%= prof.text_field :school %>
</div>
<div class="field">
<%= prof.label :college %><br />
<%= prof.text_field :college %>
</div>
<div class="field">
<%= prof.label :higher_education %><br />
<%= prof.text_field :higher_education %>
</div>
<div class="field">
<%= prof.label :certification %><br />
<%= prof.text_field :certification %>
</div>
<div class="field">
<%= prof.label :about_video %><br />
<%= prof.text_field :about_video %>
</div>
<div class="field">
<%= prof.label :interested_in_learning %><br />
<%= prof.association :categories, :label => "Interested in learning", :wrapper_html => { :id => "iil_multiselect", :class=> "signup_field", :multiselect => true }%>
</div>
<!--<div class="field">
<%# prof.label :interested_in_learning %><br />
<%# prof.text_field :interested_in_learning %>
</div>-->
<div class="field">
<%= prof.label :would_like_to_teach %><br />
<%= prof.text_field :would_like_to_teach %>
</div>
<% end %>
<div><%= f.submit "Save" %></div>
<% end %>
<h3>Cancel my account</h3>
<p>Unhappy? <%= button_to "Cancel my account", registration_path(resource_name), :data => { :confirm => "Are you sure?" }, :method => :delete %></p>
My profile pic is not seen in the profile/show page What am i doing wrong?

How to avoid "Can't mass-assign protected attributes" error

Even though I added accepts_nested_attributes_for to my model.
it still says "Can't mass-assign protected attributes"
What else am I supposed to do in order to avoid this???
models/user.rb
class User < ActiveRecord::Base
validates_presence_of :username
validates_uniqueness_of :username
validates_length_of :username, :within => 4..10
acts_as_messageable
has_one :user_profile
accepts_nested_attributes_for :user_profile
# Include default devise modules. Others available are:
# :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable, :confirmable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me, :username, :user_profile_attributes
def mailboxer_email(message)
email
end
# def name
# email
# end
end
models/user_profile.rb
class UserProfile < ActiveRecord::Base
belongs_to :user
accepts_nested_attributes_for :user
attr_accessible :nickname
end
views/registration/edit.html.erb
<h2>Edit <%= resource_name.to_s.humanize %></h2>
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put }) do |f| %>
<%= devise_error_messages! %>
<div class="field">
<%= f.label :nickname %><br />
<%= f.fields_for :nickname_attributes, #user.user_profile do |user_profile| %>
<%= user_profile.text_field :nickname %>
<% end %>
</div>
<div><%= f.label :email %><br />
<%= f.email_field :email %></div>
<div><%= f.label :password %> <i>(leave blank if you don't want to change it)</i><br />
<%= f.password_field :password %></div>
<div><%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %></div>
<div><%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
<%= f.password_field :current_password %></div>
<%= recaptcha_tags :display => {:theme => 'red'} %>
<div><%= f.submit "Update" %></div>
<% end %>
<h3>Cancel my account</h3>
<p>Unhappy? <%= link_to "Cancel my account", registration_path(resource_name), :confirm => "Are you sure?", :method => :delete %>.</p>
<%= link_to "Back", :back %>
attr_accessible defines the attributes you want the user to be able to mass assign. Just make sure it has all the attributes you want in there.
To be fair, you can remove attr_accessible if you don't care about it and the error will disappear (but all your model fields will be mass assignable).
in edit.html.erb
wrong:
f.fields_for :nickname_attributes,
correct:
f.fields_for :user_profile_attributes,

rails devise: user and account system

I've been trying to add an account to a user for a couple of days now.
I've installed Devise with no problems, but now I wanted to add a Company Name field to my registration form.
Here's my code:
app/models/account.rb
class Account < ActiveRecord::Base
attr_accessible :name
has_many :users
accepts_nested_attributes_for :users
end
app/models/user.rb
class User < ActiveRecord::Base
belongs_to :account
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :confirmable
attr_accessible :first_name, :last_name, :account_attributes, :account, :email, :password, :password_confirmation, :remember_me
end
app/views/devise/registrations/new.html.erb
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div><%= f.label :first_name %><br />
<%= f.text_field :first_name %></div>
<div><%= f.label :last_name %><br />
<%= f.text_field :last_name %></div>
<%= f.fields_for :account do |account_form| %>
<div><%= account_form.label :name %><br />
<%= account_form.text_field :name %></div>
<% end %>
<div><%= f.label :email %><br />
<%= f.email_field :email %></div>
<div><%= f.label :password %><br />
<%= f.password_field :password %></div>
<div><%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %></div>
<div><%= f.submit "Sign up" %></div>
<% end %>
This is all the code I have. I haven't changed anything more.
And this is the error I got:
Account(#2175324980) expected, got ActiveSupport::HashWithIndifferentAccess(#2169631580)
Thanks in advance.
EDIT
I've found the solution:
I've changed
<%= f.fields_for :account do |account_form| %>
To
<%= f.fields_for :account_attributes, resource.account do |account_form| %>
Now I'm trying to add a :plan to account_form and I'm getting:
Can't mass-assign protected attributes: plan
EDIT 2
Ok, rookie mistake. I've just added :plan to account model.
After that I was getting an query error, I just changed some fields in my DB from null => false to null => true and voila.
I would expect it to look something like this. This involves subclassing devise's registrations controller
#models
class Account < ActiveRecord::Base
attr_accessible :name
has_many :users
end
class User < ActiveRecord::Base
belongs_to :account
accepts_nested_attributes_for :account
attr_accessible :first_name, :last_name, :account_attributes, :account, :email, :password, :password_confirmation, :remember_me
end
#app/controllers/registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
def new
#account = Account.new
super
end
end
#routes
devise_for :users, :controllers => {:registrations => "registrations"}
#view
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div><%= f.label :first_name %><br />
<%= f.text_field :first_name %></div>
<div><%= f.label :last_name %><br />
<%= f.text_field :last_name %></div>
<%= f.fields_for #account do |account_form| %>
<div><%= account_form.label :name %><br />
<%= account_form.text_field :name %></div>
<% end %>
<div><%= f.label :email %><br />
<%= f.email_field :email %></div>
<div><%= f.label :password %><br />
<%= f.password_field :password %></div>
<div><%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %></div>
<div><%= f.submit "Sign up" %></div>
<% end %>

Resources