ROR Devise: allowing username or email logins: undefined local variable - ruby

I've been following the tutorial on the Devise github page here: https://github.com/plataformatec/devise/wiki/How-To:-Allow-users-to-sign_in-using-their-username-or-email-address
I'm in the second part of the tutorial where we allow users to recover their password using either their username or email and there's a large block of code that the tutorial says to copy into the User model. This is the line that throws an error:
def self.find_record(login)
where(attributes).where(["username = :value OR email = :value", { :value => login }]).first
end
This is the error I get:
NameError (undefined local variable or method `attributes' for #<Class:0xa70e1a8>):
app/models/user.rb:63:in `find_record'
app/models/user.rb:44:in `find_recoverable_or_initialize_with_errors'
app/models/user.rb:30:in `send_reset_password_instructions'
Anyone know why this error is showing up?

You're not passing in any attributes, and there's no 'attributes' class method, so where(attributes) doesn't work. It doesn't look like you need to either. Change your method to:
def self.find_record(login)
where(["username = :value OR email = :value", { :value => login }]).first
end
For what it's worth, I don't see how it would have worked in the tutorial either.

Related

Record Not Found rails 5 ActiveRecord Error

I am trying to use a vanity URL that uses the SecureRandom issued ident to a culvert, and then display that culvert via the show page.
This is a screenshot of the error message:
This is a screenshot of the browser url:
My Culvert Controller is:
I have tried Both:
#culvert = Culvert.find_by_culvert_ident(params[:id])
AND
#culvert = Culvert.find_by_id(params[:culvert_ident])
In my culvert controller show action, both yield the same result (screenshot)
private
# Use callbacks to share common setup or constraints between actions.
def set_culvert
#culvert = Culvert.find_by_culvert_ident(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def culvert_params
params.require(:culvert).permit(:culvert_ident, :latitude, :longitude, :address, :user_id)
end
This is my Culvert Model ident generator and vanity url methods:
before_create :generate_culvert_ident
# Relationships
belongs_to :user
# Model Validations
validates_uniqueness_of :culvert_ident
# Ident Generator
def generate_culvert_ident
begin
self.culvert_ident = SecureRandom.hex(3).upcase
other_culvert = Culvert.find_by(culvert_ident: self.culvert_ident)
end while other_culvert
end
# Url Direction
def to_param
culvert_ident
end
So my goal is to create the culvert, auto assign a unique identifier, save it and display the culvert using the custom identifier as opposed to the standard 1,2,3,4 id's
this works in another web app i have used, is setup exactly the same but i am getting this error here and cant figure out why. Please let me knwo if you require further info!
**
EDIT # 1 - Adds Screenshot of Console output
**
So the issue here was that I removed the culverts controller
before_action :set_culvert
as soon as I re-added the set_user action the issue was resolved.
thanks for your assistance!

undefined method update_attributes in Rails 4

i'm now using Rails 4
now i want to update my user record
i'm trying to use this command
#user=User.update_attributes(:name=> params[:name], :user=> params[:username], :pass=> params[:password])
OR
#user=User.update_attributes(name: params[:name], user: params[:username], pass: params[:password])
but always got the error
undefined method `update_attributes'
so how i can update my user
also i want to ask is it will update all the users in my DB ??
i think i must add some condition such as where id=#user.id but i don't know how i can do that in rails !!!
update_attributes is an instance method not a class method, so first thing you need to call it on an instance of User class.
Get the user you want to update :
e.g. Say you want to update a User with id 1
#user = User.find_by(id: 1)
now if you want to update the user's name and password, you can do
either
#user.update(name: "ABC", pass: "12345678")
or
#user.update_attributes(name: "ABC", pass: "12345678")
Use it accordingly in your case.
For more reference you can refer to Ruby on Rails Guides.
You can use update_all method for updating all records.
It is a class method so you can call it as
Following code will update name of all User records and set it to "ABC"
User.update_all(name: "ABC")
It seems that the "update_attributes" method is not working anymore!
You must use the "update" method like this:
#user=User.update(:name=> params[:name], :user=> params[:username], :pass=> params[:password])

Undefined method `[]' for nil:NilClass when trying to pull value from hash

I'm new to Ruby, and for the most part it's starting to make sense, but then I came across this problem.
I searched for a user using:
user = User.find_by_id(user_id)
I can do user.inspect and it displays as:
#<User id: 1, username: "test_user", first_name: "test", last_name: "user">
However, when I try to do:
user[:id]
I get:
undefined method `[]' for nil:NilClass
What am I overlooking?
Here is the user.rb:
class User < ActiveRecord::Base
# Validations
validates :first_name, :last_name, :presence => true
validates :username, :uniqueness => {:allow_blank => true}
# Setup accessible (or protected) attributes for your model
default_fields = [:username, :first_name, :last_name]
attr_accessible *default_fields
# Instance Methods
def full_name
"#{first_name} #{last_name}"
end
end
Additionally, if I do:
user.to_s
it results in:
#<User:0x007fdad09717f8>
Which further leads me to believe that it's not nil, but yet I can't reference the hash values.
your first sentence
user = User.find_by_id(user_id)
returned a null object, so you need to test this in order to avoid the exception:
if( ! user.nil? )
# code with user[:id]
end
So the problem turns out not to be related to code, but to data in a Database table that I was using to get the 'user_id' value. Thats what I get for trusting that someone else would have written proper validations on all the models in the project.
Thats everyone for helping me resolve this, if I hadn't needed to create a minimum example that reproduced the issue I never would have stumbled across the bad entry in the database.
So to use Miguel Prz's Idea I ended up doing this:
user.nil? ? '' : user[:id]
This is further proof why I should never trust anyone else's work :)

DataObject::Integrity error in DataMapper

I wrote an app where I plan to save user data via DataMapper and sqlite3, and inventory items (several of them) using GDBM. When I run this with irb, User.new and inventory methods works fine however DataMapper says that my user model is not valid and does not save it. I worked with DataMapper previously and never encountered such an error, in fact I used the same user model (with password salt and hash) without any errors in a sinatra-datamapper app.
To be clear, I intend to save both the username and 'the path to the gdbm database file' as a string in datamapper. The gdbm creates its own db file and all methods work fine without complaints and all data is persistent. Since I am not trying to save the gdbm object but only a string in datamapper, I think there should be no problem of validation.
DataMapper::Model.raise_on_save_failure = true does not give a specific description of the error but save! method gives the following error:
DataObjects::IntegrityError: users.name may not be NULL (code: 19, sql state: , query: INSERT INTO "users" DEFAULT VALUES, uri: sqlite3:/home/barerd/game_inventory/users.db?scheme=sqlite3&user=...... but name attribute is not empty as I checked in irb.
Maybe the error originates from sqlite but I have no knowledge to test that. Can someone guide me how to inspect this error?
require 'gdbm'
require 'data_mapper'
require 'dm-validations'
DataMapper.setup :default, 'sqlite://' + Dir.pwd + '/users.db'
class User
attr_reader :name, :inventory_db
include DataMapper::Resource
property id, Serial
property :name, String, :required => true, :unique => true, :messages => { :presence =>...... etc }
property :inventory_db, String
def initialize name
#name = name
#inventory_db = Dir.pwd + '/#{name}_inventory.db'
end
def inventory
GDBM.new #inventory_db, 0644, GDBM::WRCREAT
end
..several methods related to inventory..
end
DataMapper.finalize.auto_migrate!
Googling further, I found out that
there is a guard around defining property getter in dkubb/dm-core
via this link. After removing getter methods from the model, everything worked fine.

Rails 3 AJAX: wrong constant name

I am trying to do Ajax login with Devise, as explained here: http://jessehowarth.com/2011/04/27/ajax-login-with-devise#comment-5 (see comment from jBeasley).
My controller is attempting to return
class Users::SessionsController < Devise::SessionsController
def failure
render :json => {:success => false, :errors => ["Login failed."]}
end
end
which results in this error:
NameError (wrong constant name ["{\"success\":false,\"errors\":[\"Login failed.\"]}"]Controller):
and Firebug showing [500 Internal Server Error].
How can I fix this? I am running Rails 3.1 and devise 1.4.5.
Thanks!!
Did you do the step recommended by Jeff Poulton in comment #4? The :recall option in 1.4.5 looks to be completely incompatible to older versions. It now requires you send the controller, whereas in the tutorial you're following he just sends the action (the old way).
In your case, :recall => :failure must be changed to :recall => "users/sessions#failure" in Devise 1.4.5.
This is because of the way the controller for the failure action is determined. In older versions, it was simply pulled from the params.
def recall_controller
"#{params[:controller]}.camelize}Controller".constantize
end
# called via recall_controller.action(warden_options[:recall]).call(env)
In 1.4.5, it expects a string specifying the controller and action, in the style of routes:
def recall_app(app)
controller, action = app.split('#')
controller_name = ActiveSupport::Inflector.camelize(controller)
controlller_klass = ActiveSupport::Inflector.constantize("#{controller_name}Controller")
controller_klass.action(action)
end
# called via recall_app(warden_options[:recall]).call(env)
It would seem as though your app is actually passing the JSONified hash of options to recall_app, which, lacking a '#', isn't being split, and the entire string is concatenated to "Controller" to attempt to ascertain the failure controller's class.
You are missing the return in
def failure
return render:json => {:success => false, :errors => ["Login failed."]}
end
Does that make a difference?

Resources