views:

106

answers:

2

In rails, I know it is best to do a find through scope

e.g in questions_controller

def index
  @event = Event.find(params[event_id])
  @question = @event.questions
end

but is it also good practice to then do the same in the show action

def show
  @event = Event.find(params[:event_id])
  @question = @event.questions.find(params[:id])
end

or better to just do a find straight on the Question model without scoping it through the event?

I am curious about that and also doing a similar thing with @question.comments.build vs Comment.new when making a new record without creating a question record at the same time.

thanks

+1  A: 

If you are only getting the event to get a question, doing Event.find is unnecessary and causes additional work.

Both of the actions you wrote perform two queries.

Tilendor
Assuming "id" is unique (and thus indexed), then having "event_id" in the where-clause will not cause any slowdown. The planner will automatically do the right thing (use the id-index). It might however make sense seen from a security/data-integrity standpoint to have it in there.
Edit response based on comment. Thanks.
Tilendor
+1  A: 

As to your first question a few things to keep in mind:

  • What if you suddenly need @event in your view?
  • What if you want to extend Event.find with some custom logic (i.e. access control)?
  • Are there reasons not to go by the Event interface?

Personally I would go for using Event's interface for fetching the question(s) if merely to avoid premature optimization.

As for your second question, @question.comments.build will automatically set the right references in your new structure, so I'd go for that as long as @question is available. (Heck, I'd even consider making a @question.add_comment(..) method to the Question class).

Put in other words, premature optimization is the root of all evil. And loose coupling is good for you.

RE: the first 2 bullets:Build for what you know you need. If you don't need it now, don't write it. If you write code for something you *might* need, then you probably will have done it wrong because you didn't know the details. Or you will end up not needing it, and will have useless code.
Tilendor