0

I want to check if a record already exist in my database. In my function i have this code:

mailcode = params[:q] check = User.where("custom_mailcode = 'mailcode'").first 

Now i'm in trouble with the if statement. I think to do something like that:

if check == nil doing something else doing something end 

But it doesn't work because check is never nil. How can i fix that?

3
  • This is weird, if no user is found matching the the given where-clause, calling .first would return nil so it should just work. Commented Jul 16, 2015 at 10:22
  • Sounds like a classic XY problem to me. What do you indend to do with that item in case it exists or not? Commented Jul 16, 2015 at 10:43
  • And FYI where(...).first is typically done via find_by(...). Commented Jul 16, 2015 at 10:45

6 Answers 6

1

You could try

User.where("custom_mailcode = 'mailcode'").any?

Sign up to request clarification or add additional context in comments.

2 Comments

As a side-point, you might want to define the condition as a named scope. something like named_scope :with_mailcode, lambda {|code| where(:custom_mailcode => code)}
Well, any? returns true or false, so you wouldn't then do if check == nil, just if check.
1

If you intend to use the user record you can instead use find_by

user = User.find_by(custom_mailcode: params[:q]) # User / nil if user # ... else # ... end 

find_by unlike where returns the first record or nil.

If you do not plan on using the database values than use .any? it will issue a COUNT SQL query which is slightly faster and uses less memory.

# ActiveRecord only loads a boolean into memory if User.where(custom_mailcode: params[:q]).any? # ... else # ... end 

Comments

0

You could do

if check.present? ... else ... end 

1 Comment

Calling .first on a relation will either return nil or the first object, so while this more readable, how does this fix the question?
0

You can do the following:

if check = User.where(custom_mailcode: params[:q]).first p check else doing something else end 

Comments

0

Ha I see the error, the error is not in your check, but in your where-clause. You are always looking for a fixed string called mailcode, not the value of the variable. The easiest fix is just to write the where differently:

check = User.where(custom_mailcode: params[:q]).first 

Or use proper string interpolation

check = User.where("custom_mailcode = '#{mailcode}'").first 

which you should avoid, because this makes your application vulnerable to SQL injection attacks; just showing the proper way to do string interpolation.

And then you just test

if check == nil 

But I personally prefer check.nil?.

3 Comments

Use find_by(ustom_mailcode: params[:q]) instead of .where(custom_mailcode: params[:q]).first the latter is just bad style.
Nope the return value is the same - if you don't need the user use any? or count which issues a count query.
Yes, I was very good at not really reading your comment apparently. I do not agree on the style argument, I find the where-first combination very readable, and it allows to combine various where clauses, as you usually do, and it results in the same query as the find_by. So imho it is just a matter of personal taste to use either one. But it is a good suggestion.
0

I assume you want to modify or read the user if it's found. That can be accomplished like this:

mailcode = params[:q] user = User.find_by(custom_mailcode: mailcode) if user # do something with the user else # backup logic end 

Or, as is often needed, you may want to create the object, if it's not already found. There's a find_or_create_by shorthand for that purpose:

mailcode = params[:q] user = User.find_or_create_by(custom_mailcode: mailcode) user.update(meaning_of_life: 42) 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.