I added validation to my user.db and when I try to sign up it doesn't really work. When I don't enter the username, it says that that field can't be blank - which is correct. However, if the field is filled in, it still says that the field can't be blank and doesn't allow me to register. This is my model:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable, :rememberable, :trackable, :validatable
validates :name,
:presence => true,
:uniqueness => {
:case_sensitive => false
}
has_many :pins
end
#:recoverable
View
<%= simple_form_for(resource, as: resource_name, url: registration_path(resource_name), html: { class: 'form-horizontal'}) do |f| %>
<%= f.error_notification %>
<div align='center'>
<h2>Sign up</h2><br>
<div class='field_center'>
<%= f.input :name %>
<%= f.input :email %>
<%= f.input :password %>
<%= f.input :password_confirmation %>
</div>
<div class="form-actions">
<%= f.submit "Sign Up", class: "btn btn-primary btn-lg" %>
</div>
<% end %>
<br>
<%= render "devise/shared/links" %>
</div>
Not sure, if it's going to be helpful, but can you please check what parameters are sent at the POST action at the shell running the web server? Make sure the params are sent for :name attribute and they're not empty.
If the params for name are really empty in web server log, check your view. I had a similar case when a unclosed tag in erb resulted in a weird behavior with Devise (empty params as well).
Related
I have a strange problem with my rails app. I have several forms not working when I try to submit them coming from a direct link. For example, if I click on "log in" from the home page, it does not work. But if I refresh the page, then I can submit the form. Any idea what's the problem?
Log in view new.html.erb:
<div class="main-container form">
<h2>Log in</h2>
<div class="form-fields">
<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true %>
</div>
<div class="field">
<%= f.label :password %><br />
<%= f.password_field :password, autocomplete: "off" %>
</div>
<% if devise_mapping.rememberable? %>
<div class="field">
<%= f.check_box :remember_me %>
<%= f.label :remember_me %>
</div>
<% end %>
</div>
<div class="footer-form">
<div class="actions">
<%= f.submit "Log in", class: 'cta' %>
</div>
<div class="links-form">
<%= render "devise/shared/links" %>
</div>
</div>
<% end %>
</div>
User model:
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :review
before_create :add_random_id
private
def add_random_id
self.random_id = SecureRandom.uuid unless self.random_id
end
end
Routes:
devise_for :users, controllers: {registrations: 'registrations'}
Thank you.
I just removed the following line in my application.js file and it works:
//= require turbolinks
I have my login form, and my js mask, all ok. But where I put the code:
cpf.gsub!(/(\.|\-)/, "")
For mask work?
I need generate devise's controller for put on login or just model? I need User 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
before_validation do
self.cpf.gsub!(/(\.|\-)/, "")
end
end
But it just work with registration user, dont login.
My login is this:
<div class="login">
<div class="panel panel-default">
<div class="panel-heading"><h4 class="cor-texto">AUTENTICAÇÃO DO USUÁRIO</h4></div>
<div class="panel-body">
<%= simple_form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
<div class="form-inputs">
<div class="form-group">
<%= f.input :cpf, required: false, autofocus: true, input_html: { class: 'form-control mascara-cpf' }, placeholder: 'LOGIN', label: false %>
</div>
<div class="form-group">
<%= f.input :password, required: false, input_html: { class: 'form-control' }, placeholder: 'SENHA', label: false %>
</div>
<div class="espaco-check-box-login">
<%= f.input :remember_me, label: 'Lembre-me', as: :boolean if devise_mapping.rememberable? %>
</div>
</div>
<div class="form-actions">
<%= f.button :submit, "Log in", :class => "btn btn-default btn-lg btn-block" %>
</div>
<% end %>
</div>
</div>
</div>
My mask work into form, but save on DB with . and -, because this I cant sign in on system =(
Check this out, it explains how before_validation works
Defines a callback that will get called right before validation
happens.
It won't work because you're trying to do a POST request in a login action, which will not call the before_validation.
What I recommend you to do is unmask the value before the form gets submitted via js, or before the authentication method is called inside your controller.
Hope this helps!
A good way, according devise documentation is, override login query in your user.db like:
def self.find_for_database_authentication(warden_conditions)
conditions = warden_conditions.dup
if cpf = conditions.delete(:cpf)
logger.debug cpf.gsub!(/[^\d]/, '')
where(conditions).where(["cpf = :value", { :value => cpf }]).first
end
I've checked a few answers to similar problems, and all seem to suggest the problem is attr_accessible, but I just can't seem to get this working.
Basically I have User & Address model,and want to assign Address attributes as nested attributes. But when I save it causes the can't mass-assign attributes error shown below.
I've tried many variations of attr_accessible in below code, like :addresses_attributes, :address_attributes, :primary_address_attributes...I'm not sure why it's not working,perhaps because it's in the Member module declaration??
Can anyone help?
class Member::User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
# each user may have zero or many addresses
# their primary email is also set as their login id.
has_many :addresses
has_one :address, :class_name => "Member::Address", :conditions => "is_primary = true"
accepts_nested_attributes_for :addresses, :address
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me, :address_attributes
validates_presence_of :email
end
My form that submits the nested fields (relevant parts of)
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => {:class => "form-horizontal"}) do |f| %>
<small>Mandatory fields marked *</small><br><br>
<% devise_error_messages! %>
<% flash.each do |name, msg| %>
<div class="alert alert-<%= name == :notice ? "success" : "error" %>">
<a class="close" data-dismiss="alert">×</a>
<%= msg %>
</div>
<% end %>
<%= f.fields_for resource.build_primary_address do |address_form| %>
<div class="control-group">
<%= address_form.label :first_name, :class => "control-label" %>
<div class="controls">
<%= address_form.text_field :first_name, :class => "input-xlarge" %>
</div>
</div>
<div class="control-group">
<%= address_form.label :last_name, :class => "control-label" %>
<div class="controls">
<%= address_form.text_field :last_name, :class => "input-xlarge" %>
</div>
</div>
<% end %>
The error shows this:
Can't mass-assign protected attributes: member_address
{"utf8"=>"✓",
"authenticity_token"=>"HrZJG2krn15veUKJVh6PgEs4wwufaeRhciHcUIn6AaM=",
"user"=>{"member_address"=>{"first_name"=>"asdf",
"last_name"=>"asdfsafd"},
"email"=>"Bob.JOnes#jones.com",
"password"=>"[FILTERED]",
"password_confirmation"=>"[FILTERED]"}}
In order for rails to understand that that the primary address being submitted in the form is a nested attribute, you have to explicitly tell it the relation here:
<%= f.fields_for :address, resource.build_primary_address do |address_form| %>
. The reason is, because your model names are scoped with Member::, and rails derives form parameter names from the class names, in your params hash you end up with :member_address instead of :address. Because :address in this case is a field for which :user accepts nested attributes, :address should be represented as :address_attributes in the params hash, so make sure the latter appears in attr_accessible.
Add
attr_accessible :member_address
to the User model.
Explanation: every hash key that you want to initialize an ActiveRecord instance with must be stated as attr_accessible. Looking at your hash keys there is:
"user"=>{"member_address"=>{ ... }}
member_address key in the hash which initializes the User instance, thus it has to be included in the attr_accessible statement.
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,
I'm using Devise for user registration. I've been reading the all famous tutorial about customizing Devise, but can't understand this simple task. I followed his model (HABTM)
I want to add a roles check box to the Devise edit form. I don't have a Controller cause Devise doesn't provide one, but managed to add a default role to new users. I was able to display the checkboxes with the correct info checked but can't edit it (it won't save anydata). Do I need a custom controller? if yes, how exactly? I'm new to HABTM relations!
My User model
class User < ActiveRecord::Base
has_and_belongs_to_many :roles
before_save :setup_role
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable, :lockable and :timeoutable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me
def role?(role_sym)
roles.any? { |r| r.name.underscore.to_sym == role_sym }
end
# Default role is "User"
def setup_role
if self.role_ids.empty?
self.role_ids = [3]
end
end
end
My edit form (devise/registrations/edit.html.rb
<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! %>
<p><%= f.label :email %><br />
<%= f.text_field :email %></p>
<p><%= f.label :password %> <i>(leave blank if you don't want to change it)</i><br />
<%= f.password_field :password %></p>
<p><%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %></p>
<p><%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
<%= f.password_field :current_password %></p>
<% for role in Role.find(:all) %>
<div>
<%= check_box_tag "user[role_ids][]", role.id, #user.roles.include?(role) %>
<%= role.name %>
</div>
<% end %>
<p><%= f.submit "Update" %></p>
<% 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 %>
check your console, I was getting a 'Can't mass assign" error, then I put :role_ids into the user model's attr_accessible and it worked.