Dennis Hackethal
Dennis Hackethal

Reputation: 14295

Pass object or id

This is just a question about best practices.

Imagine you have a method that takes one parameter. This parameter is the id of an object. Ideally, I would like to be able to pass either the object's id directly, or just the object itself.

What is the most elegant way to do this?

I came up with the following:

def method_name object
  object_id = object.to_param.to_i
  ### do whatever needs to be done with that object_id
end

So, if the parameter already is an id, it just pretty much stays the same; if it's an object, it gets its id.

This works, but I feel like this could be better. Also, to_param returns a string, which could in some cases return a "real" string (i.e. "string" instead of "2"), hence returning 0 upon calling to_i on it. This could happen, for example, when using the friendly id gem for classes.

Active record offers the same functionality. It doesn't matter if you say:

Table.where(user_id: User.first.id) # pass in id

or

Table.where(user_id: User.first) # pass in object and infer id

How do they do it? What is the best approach to achieve this effect?

Upvotes: 9

Views: 4280

Answers (2)

Sergio Tulentsev
Sergio Tulentsev

Reputation: 230521

My guess is that ActiveRecord does something like this. Or, rather, that's how I'd do it.

def my_method(oid)
  oid = oid.id if oid.respond_to?(:id)

  # proceed
end

Upvotes: 9

Billy Chan
Billy Chan

Reputation: 24815

If the process is cross controller actions or in session, better to use id. For example, you are going to save a cart in session, the better choice is id. It's hard to watch how big an object is, using id will help performance and avoid unnecessary error.

However, if the methods are inside same request and all actions are within memory, using object itself would be quicker. For example, you pass an user to an authority class to check if he can do something. Because all objects are just a reference in memory, extra step to extract id is unnecessary and inefficient.

Upvotes: 12

Related Questions