vlasits
vlasits

Reputation: 2235

Passing (and using) parameters to the "new" action of a controller

My app has Lessons which have many Drills.

When I am looking at a lesson I want to be able to create new Drills and automatically assign their lesson_id.

So far what I have is a link in the lesson's show.html.erb that passes in the lesson's id, like so:

<%= link_to t('.new', :default => t("helpers.links.new")),
          new_drill_path(lesson_id: @lesson.id), :class => 'btn' %>

This adds the lesson_id to the params hash. I figured out how to pass the param into the drill by doing this in my controller:

  def new
    @drill = Drill.new
    params.each do |key, value|
      method = key.to_s + '='
      method.to_sym
      if @drill.respond_to? method
        @drill.send method, value
      end
    end
  end

However, this code seems smelly to me. It seems like there ought to be a more rails-y way to do it, but I can't figure out what it is.

Upvotes: 0

Views: 106

Answers (2)

Flambino
Flambino

Reputation: 18773

Use nested resources. Something like this:

# in config/routes.rb
resources :lessons do
  resources :drills
end

That'll give you nested URLs/routes, and route helpers like lesson_drills_path that take a Lesson-record as its argument to produce a path like /lessons/:lesson_id/drills.

Your DrillsController will therefore have access to params[:lesson_id] because it'll be given in the URL. That means that you can do things like

# POST /lesson/:lesson_id/drills/
def create
  @lesson = Lesson.find(params[:lesson_id])
  @drill = @lesson.drills.new(params[:drill])
  if @drill.save
    ..
  else
    ..
  end
end

See more in this answer over on CodeReview, and check the links in there too

Upvotes: 2

Andy Waite
Andy Waite

Reputation: 11076

I'm not exactly sure what you're trying to do, but read up on Nested Resources. Your new action should look something like:

def new
  @lesson = Book.find(params[:lesson_id])
  @drill = @lesson.drills.build
end

Upvotes: 1

Related Questions