Reputation: 2235
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
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
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