I have Devise setup on a Rails Model:
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable
I also have validation on the same model:
before_validation :geocode_address, :on => :create
When I create new User the geocode_address gets called which is what I want to do but it also gets kicked when the user logs in (creates new Devise Session) which is what I don't want.
Do you know how I can fix that?
This probably happens because the model gets validated on user log in as well. I think that it would be a better idea to utilize after_create on your model, like :
after_create :your_method
def your_method
...
end
Details : http://ar.rubyonrails.org/classes/ActiveRecord/Callbacks.html#M000061
Related
I have a form to save information to a database for my website. Even though the form does not require a sign in, whenever I try to submit the form, I get an error "Validation failed: Password can't be blank". I'm not sure why this is happening as there is no password field in the form. Here is the code from the controller, the error is from the save line:
def create
#newinstructor = Instructor.new
#newinstructor_app = InstructorApp.where(first_name: params['instructor']['first_name']).where(last_name: params['instructor']['last_name'])
#newinstructor.first_name = params['instructor']['first_name']
#newinstructor.last_name = params['instructor']['last_name']
#newinstructor.story = params['instructor']['story']
#newinstructor.save!
Here is the instructor.rb:
class Instructor < ActiveRecord::Base
has_many :activities
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :activities
has_one :instructor_app
end
You should be able to fix, by following either of the following approaches:
Remove the :validatable option from your Instructor, devise option should now be:
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable
OR
add the following method to your Instructor
def password_required?
false
end
Let me know if that helps
It looks like you have Devise modules like :database_authenticatable in your instructor model. You cant see it but Devise expects there to be a password field by default. If there's no login for your instructor form then one option is to simply delete the devise modules. Devise is generally used for the User model if you have one, to authenticate when a user initially signs up and/or logs in
I'm trying to use Devise with React.rb, so I thought I'll move my user model to the public directory to be able to edit it through React, however I get this error:
ActionView::Template::Error(User.devise(database_authenticatable,registerable,recoverable,rememberable,trackable,validatable) (called class method missing)):
1: <%= react_component #component_name, #render_params, { prerender: !params[:no_prerender] } %>
You probably have some devise specific macros in your user model.
for example if you user model looks like this:
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
# etc...
end
then you will need to insure the devise call only runs on the server like this:
class User < ActiveRecord::Base
unless RUBY_ENGINE=='opal'
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
# etc...
end
Reactive-Record stubs and proxies all the standard active-record macros like scope, and belongs_to on the client. However it doesn't know what the devise method means, so wrapping it in unless RUBY_ENGINE=='opal will prevent this from being called on the client.
FYI I added an issue https://github.com/catprintlabs/reactive-record/issues/17 to reactive-record to cover this...
I'm trying to figure out how to create a new profile for the user that has just been created,
I'm using devise on the User model, and the User model has a one to one relationship with the UserProfile model.
Here's what my User Model looks like:
class User < ActiveRecord::Base
has_and_belongs_to_many :roles
belongs_to :batch
has_one :user_profile
after_create :create_user_profile
def create_user_profile
self.user_profile.new(:name => 'username')
end
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
This generate the following error:
undefined method `new' for nil:NilClass
i've tried User.find(1).user_profile in rails c and that works so I'm pritty sure the relationship is setup correctly,
I'm probably being a big fat noob and trying to fetch self incorrectly.
plus can you also tell me how to access the params in a Model... is that even possible?
A has_one relationship will automatically add the :create_<relationship> and build_<relationship> methods. Checkout the rails guide.
You could try this:
after_create do
create_user_profile(:name => 'username')
end
Or more likely
after_create do
create_user_profile(:name => self.username)
end
I have a rails 3.2 app with Devise 2.1
I have 2 models using devise (AdminUser and User)
Models:
class AdminUser < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
I have generated separate views for both models via the devise generator.
views/devise folder for AdminUser (implemented months earlier before new requirement)
views/users folder for User model
After signout, I want to redirect to specific actions that match the devise models. The code below works in application_controller.rb but it is applying to both models which I want to do without:
def after_sign_out_path_for(user)
user_landing_path
end
Signing out of either model redirects to the same landing page, but i would like to have a unique destination for both devise models.
How can I achieve this?
I figured out what seems to be a solution after looking at some examples here
http://eureka.ykyuen.info/2011/03/10/rails-redirect-previous-page-after-devise-sign-in/
def after_sign_out_path_for(resource_or_scope)
case resource_or_scope
when :user, User
user_landing_path
when :admin_user, AdminUser
admin_user_landing_path
else
super
end
end
Some things you could do:
case user.class
when AdminUser.class
do_admin_sign_out()
when User.class
do_user_sign_out()
else
no_idea_who_you_are()
end
or
if user.kind_of? AdminUser
do_admin_thing()
else
do_user_thing()
end
alternatively, you could add an admin? check to both models, and check that, ie:
if user.admin?
do_admin_thing()
...
I would probably do the later, as this might come up else where, but these are among your options.
I'm using devise_invitable to allow users to invite each other. I want to set values for the user when the invite is created or when it's accepted. One approach is here
Using devise_invitable for adding Users to a Group in Ruby on Rails?
but this seems overkill. The callbacks look like a perfect solution, but they don't seem to fire during my Rspec tests.
Here is the user model:
class User < ActiveRecord::Base
belongs_to :company
rolify
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :invitable, :database_authenticatable, :registerable, :confirmable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :role_ids, :as => :admin
attr_accessible :name, :email, :password, :password_confirmation, :remember_me, :company
validates :company, :presence => true
after_invitation_accepted :email_invited_by
before_invitation_accepted :email_invited_by
private
def email_invited_by
# This is NEVER executed during tests, even when an invite is successfully accepted
puts "Callback worked"
end
end
Any clues about where to look would be appreciated. I find the devise_invitable documentation a bit opaque.
Thanks!
For those still looking for an answer here is what worked for me.
The issue is not with validations since in devise_invitable there is a config to validate on invite and it defaults to false:
# Flag that force a record to be valid before being actually invited
# Default: false
# config.validate_on_invite = true
So my solution is to use the callback provided by devise_invitable:
after_invitation_accepted :create_profile
Do note that this needs to be below devise :invitable
devise_invitable callbacks will be fired if the user has been really invited (i.e. the object is persisted and there's an invitation token set) and the object (user's object) has no validation errors. That said, I see that you're validating presence of company without any conditions, which, I think, could be causing validation errors.
If that's the case, you can add a condition like this
validates :company, :presence => true, :if => Proc.new { self.invitation_token.nil? }
so it won't cause validation errors and fire the callbacks.