1

I want to set a variable to a given value, but only if the value is valid.

Right now this is the code I have:

if Something.find(params[:id].comments.first.exists?
  @comment = Something.find(params[:id]).comments.first
else
  @comment = nil
end

But this is inefficient because it has to load the records twice.

I tried to use the ruby method try to ensure that the variable would only be set if the value is valid:

@comment = Something.try.find(params[:id]).comments.first

but no matter where I put it, I get back a "nil is not a symbol" error. It seems try is only for printing variables.

Anyone know how else I can accomplish this with only one query?

Joe Morano
  • 1,715
  • 10
  • 50
  • 114

4 Answers4

2

You could try:

@comment = Comment.find_by(something_id: params[:id])
xuanduc987
  • 1,067
  • 1
  • 9
  • 10
0

Did you tried?

if @comment = Something.find(params[:id]).comments.first
    # do something with your @comment variable
else
    # do something else
end

More examples: Check if record exists from controller in Rails

Community
  • 1
  • 1
soltex
  • 2,993
  • 1
  • 18
  • 29
  • This form is very easily confused by the reader for an equality test. If you're going to do this, then I suggest at least parenthesizing the entire expression to give a visual cue that something different is here: `if (@comment = Something.find(params[:id]).comments.first)` – Keith Bennett May 03 '16 at 06:10
0
# Attempt your query

@comment = Something.find(params[:id]).comments.first

# If the record does not exist, use rescue to handle the exception gracefully

rescue ActiveRecord::RecordNotFound
  # Handle the exception
  @comment = nil
end

You can find more information on exceptions and exception handling here.

MarsAtomic
  • 10,436
  • 5
  • 35
  • 56
0

I think this is what you want:

@comment = Something.find_by(id: params[:id]).try(:comments).try(:first)

In this case find_by will return a Something object or nil. In case of nil, the chain of tries will still return nil, and, in case of object, methods in tries will be executed and give you the first comment, if such exists (note! you might still get a nil if object exists because that object might not have any comments).

Thus, you will set your @comment only if Something object exists and it has comments; otherwise, it will be nil.