Anonymous user in devise - rails - ruby-on-rails

I'm new to rails and I tried to make simple authentication with anonymous user. I followed this tutorial and I have this error:
undefined method `find_or_initialize_by_token'
This is my AnonymousUser model:
class AnonymousUser < User
ACCESSIBLE_ATTRS = [:name, :email]
attr_accessible *ACCESSIBLE_ATTRS, :type, :token, as: :registrant
def register(params)
params = params.merge(type: 'User', token: nil)
self.update_attributes(params, as: :registrant)
end
end
This is my User model:
class User < ActiveRecord::Base
devise :database_authenticatable, :confirmable, :lockable, :recoverable,
:rememberable, :registerable, :trackable, :timeoutable, :validatable,
:token_authenticatable
attr_accessible :email, :password, :password_confirmation, :remember_me
end
And the last one important is my ApplicationController which has this error:
class ApplicationController < ActionController::Base
protect_from_forgery
def authenticate_user!(*args)
current_user.present? || super(*args)
end
def current_user
super || AnonymousUser.find_or_initialize_by_token(anonymous_user_token).tap do |user|
user.save(validate: false) if user.new_record?
end
end
private
def anonymous_user_token
session[:user_token] ||= SecureRandom.hex(8)
end
end
Someone told me that if AnonymousUser user inherits from User then AnonymousUser have method called find_or_initialize_by_token, but i don't know how to fix it.

Provided you have latest rails installed, try to refactor:
# in ApplicationController#current_user
AnonymousUser.find_or_initialize_by_token(anonymous_user_token).tap do |user|
user.save(validate: false) if user.new_record?
end
to something like this:
AnonymousUser.safely_find(anonymous_user_token)
and push the find_or_initialize_by_token and save(validate: false) into the model.

I wrote the blog post you referenced, but today, I would use
AnonymousUser.where(anonymous_user_token: anonymous_user_token).first_or_initialize
Dynamic finders have been deprecated AFAIK.
However, #Saurabh Jain is absolutely correct in his suggestion to refactor that block into a nice little push-button class method on the AnonymousUser.

Related

Validate presence on after_create

I have a 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_one :profile, dependent: :destroy
after_create :build_profile
end
So when the user registers, there profile is created and they are redirected to the edit_profile_page
class RegistrationsController < Devise::RegistrationsController
protected
def after_sign_up_path_for(resource)
edit_profile_path(current_user)
end
end
In my profile model I'm trying to set some validation
class Profile < ApplicationRecord
belongs_to :user
...
validates :name, presence: true
end
Im also using the friendly_id gem
profile_controller.rb
def set_profile
#profile = Profile.friendly.find(params[:id])
end
The error I'm getting is when I register a new user is:
Couldn't find Profile with 'id'=6
This only happens when I try to apply the validates :name, presence: true, without this my application works fine. I need a way to validate the name after the user is registered, after the profile model is created.
Im also getting the error at this line:
def set_profile
#profile = Profile.friendly.find(params[:id])
end
build_profile in after_create builds a profile but it doesn't persist it. It's not created in the database.
Better might be...
def after_sign_up_path_for(resource)
new_profile_path
end
In your controller
def new
#profile = current_user.build_profile
...
end
def create
#profile = current_user.build_profile
if #profile.update_attributes(profile_params)
...
end
...
end

Rails Devise No Method Error for Registrations for Stripe Checkout

I'm trying to create a registration form for paying for an event using stripe. But I'm getting an error when I submit the form.
This is the error I'm getting:
NoMethodError in Users::RegistrationsController#create
undefined method `to_sym' for nil:NilClass
Extracted source (around line #7):
def create
super do |resource|
if params[:objective]
resource.objective_id = params[:objective]
if resource.objective_id == 1
Here's my controller:
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :null_session
before_action :configure_permitted_parameters, if: :devise_controller?
# whitelist the following form fields so that we can process them
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up) { |r| r.permit(:stripe_card_token, :password, :password_confirmation, :email, :first_name, :last_name, :company, :street, :city, :state, :zip, :phone, :roadshowcity, :comments) }
end
end
My Registrations Controller (where I'm currently getting the error):
class Users::RegistrationsController < Devise::RegistrationsController
# Extend default devise gem behavior so that users
# signing up with the registration form (roadshow)
# save with a special stripe subscription function.
# Otherwise Devise signs up user as usual.
def create
super do |resource| **<====Error here(NoMethodError undefined method `to_sym' for nilclass)**
if params[:objective]
resource.objective_id = params[:objective]
if resource.objective_id == 1
resource.save_with_registration
else
resource.save
end
end
end
end
end
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
belongs_to :regis
attr_accessor :stripe_card_token, :id
# If user passes validations (email, pass, etc.),
# Call stripe and tell stripe to set up a subscription
def save_with_registration
if valid?
#product_price = Objective.find(objective_id)
customer = Stripe::Customer.create(email: email, card: stripe_card_token, description: stripe_card_token.to_s)
charge = Stripe::Charge.create(
:customer => customer.id,
:amount => 900,
:currency => "usd",
:description => "Registration"
)
self.stripe_customer_token = customer.id
save! <----- Error here(no method!)
end
end
end
The error ended up being cause by the model code:
self.stripe_customer_token = customer.id
Which should have been:
self.stripe_customer_token = charge.customer
Changing this fixed the issue.

Skip confirmation mail in devise

I want to skip the sending of confirmation mail from devise in my rails 4 application. I tried so many things, but none of them worked.
In my user.rb
before_create :my_method
def my_method
self.skip_confirmation
end
I tried this also
before_create :my_method
def my_method
!confirmed
end
I tried removing :confirmable from user.rb but none of them seems to work. Thanks in advance :)
Note: If you want to skip only on certain places
If you are calling User.create before skip_confirmation!, you need to call User.new and user.save.
#user = User.new(:first_name => "John", :last_name => "Doe")
#user.skip_confirmation!
#user.confirm!
#user.save
A/C to your way
before_create :my_method
def my_method
self.skip_confirmation!
self.confirm!
end
excluding the term confirmable in devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable should skip in a whole
Try this
#user = User.new(:email => 'email#example.com', :password => 'password')
#user.skip_confirmation_notification!
#user.save
skip_confirmation_notification! generate a confirmation token but does not send confirmation email.
Try adding this to user.rb
protected
def confirmation_required?
false
end
For every User instance:
class User < ApplicationRecord
after_initialize do |user|
user.skip_confirmation_notification!
end
end
For some particular instance:
john = User.new
john.skip_confirmation_notification!
P.S. The answers above are about disabling the confirmation process entirely, whereas the author asked about disabling just sending an email.

Omniauth callback processing after authorization

In my Rails app, I have user and authorization tables to handle users and auth data. I set up both Devise and Omniauth to use Twitter to sign up, it redirects to Twitter, but after returning to my app, it gives an error like:
NoMethodError at /users/auth/twitter/callback
undefined method `authorizations' for #<Class:0xbdc8100>
In which side, did I go wrong and how can I fix this issue?
Here are related parts: omniauth_callbacks_controller.rb:
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
def all
user = User.authorizations.from_auth(auth_hash)
if user.persisted?
flash.notice = "Signed in!"
sign_in_and_redirect user
else
session["devise.user_attributes"] = user.attributes
redirect_to new_user_registration_url
end
end
alias_method :twitter, :all
protected
def auth_hash
request.env['omniauth.auth']
end
end
authorization.rb:
class Authorization < ActiveRecord::Base
attr_accessible :uid, :provider
belongs_to :user
def self.from_auth(auth)
where(auth.slice(:provider, :uid)).first_or_create do |user|
user.provider = auth.provider
user.uid = auth.uid
end
end
user.rb:
class 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, :omniauthable, :omniauth_providers => [:twitter, :facebook]
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me, :name
# attr_accessible :title, :body
has_many :authorizations, dependent: :destroy
end
Your issue is in this line...
user = User.authorizations.from_auth(auth_hash)
You call authorizations on the class User, but as an attribute it needs to be called on an instance of the User class, i.e. a specific user.

Rails 4 + Devise 3.0.0 Adding Username

I'm working with Rails 4 and Devise 3.0.0 and am new to using these new strong paramters. I added a username to the User model using the documentation on the Devise wiki. The problem I'm running into is the strong parameters change in Rails 4.
How do I add the :login attribute to the user model to enable logging in with either the username or email?
From the rails4 readme on devise: https://github.com/plataformatec/devise/tree/rails4#strong-parameters
class ApplicationController < ActionController::Base
before_filter :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:login, :email) }
end
end
#justin.chmura
Here is a gist of how we ended up getting it working.
https://gist.github.com/AJ-Acevedo/6077336
Gist contains:
app/controllers/application_controller.rb
app/models/user.rb
config/initializers/devise.rb
You should make sure that you include the
attr_accessor :login
in the user model. Here is where I found the question explaining that attr_accessible is deprecated.
Rails 4 + Devise Login with email or username and strong parameters
Difference between attr_accessor and attr_accessible
This is what my app/models/user.rb file looks like.
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
attr_accessor :login
def self.find_first_by_auth_conditions(warden_conditions)
conditions = warden_conditions.dup
if login = conditions.delete(:login)
where(conditions).where(["username = :value OR lower(email) = lower(:value)", { :value => login }]).first
else
where(conditions).first
end
end
validates :username,
:uniqueness => {
:case_sensitive => false
}
end
It will works fine if you add an module in config/initializers as followings with all parameters,
File config/initializers/devise_permitted_parameters.rb with following contents:
module DevisePermittedParameters
extend ActiveSupport::Concern
included do
before_filter :configure_permitted_parameters
end
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:username, :email, :password, :password_confirmation) }
end
end
DeviseController.send :include, DevisePermittedParameters

Resources