MechDog
MechDog

Reputation: 548

Run block of code only if object found

Is there a cleaner way to only run a block of code if an object is found? I'm currently testing to see if the param even exists. This would error out I'm sure if there was no object. Please excuse the ugly code:

def show
  if params[:event_entry].to_i>1
    event_entry = EventEntry.find(params[:event_entry])
    #### Do something with event_entry here
  end
end

There has to be a much better way to go about this then I am...

Upvotes: 1

Views: 127

Answers (3)

Saul
Saul

Reputation: 931

An even cleaner way to do this (in Rails 4) is:

def show
  if event_entry = EventEntry.find_by(id: params[:event_entry])
    # Do something with `event_entry` here
  end
end

find_by will return nil if a record doesn't exist, see: http://api.rubyonrails.org/classes/ActiveRecord/FinderMethods.html#method-i-find_by

EDIT:

As mentioned by @apneadiving in the comment below, it would also be nice if this was done using an abstract method so you could call before_filter and the start of your controller for applicable methods (such as show, edit, update and delete). I've included an example of this below.

class EventEntriesController < ApplicationController
  before_filter :set_event_entry, only: :show

  def show
    # You have access to @event_entry because it was set before this method was called
  end

  private

  def set_event_entry
    @event_entry = EventEntry.find_by(id: params[:event_entry])
  end
end

Now you can add other methods to the before_filter line at the start of your controller to gain access to @event_entry in those methods. Something like

before_filter :set_event_entry, only: [:show, :edit, :update, :destroy]

should do the trick.

Note: You may also see before_action used in some places instead of before_filter. Either of these will work.

Upvotes: 3

MrYoshiji
MrYoshiji

Reputation: 54882

You can do the following:

def show
  if event_entry = EventEntry.where(id: params[:event_entry]).first
    # Do something with `event_entry` here
  end
end

Upvotes: 2

apneadiving
apneadiving

Reputation: 115531

I'd do:

def show
  if event_entry
    #### Do something with event_entry here
  end
end

private

def event_entry
  @event_entry ||= EventEntry.find_by(id: params[:event_entry]) # which returns nil if params[:event_entry] is nil
end

If you really want to check params[:event_entry] is present, do:

def event_entry
  return nil unless params[:event_entry]
  @event_entry ||= EventEntry.find_by(id: params[:event_entry])
end

I dont feel like checking its an integer really worth it

Upvotes: 3

Related Questions