Nutrient and Recommendation models In Rails 3, I have two models: Nutrient and Recommendation:


Nutrient has_many Recommendation
Recommendation belongs_to Nutrient


I am trying to implement the create method of the recommendation in the controller. Is this the proper way to do it?

def create
  nutrient_id = params[:recommendation][:nutrient_id]
  if nutrient_id.blank?
    #nutrient_id was blank in the submit, get other recommendation params and re-render 'new'
    params[:recommendation].delete(:nutrient_id)
    @recommendation=Recommendation.new(params[:recommendation])
    render 'new'
  else
    @nutrient = Nutrient.find(nutrient_id)
    if @nutrient
      #nutrient was found by id, create recommendation
      @recommendation = @nutrient.recommendations.build(params[:recommendation])
      if @recommendation.save
        redirect_to @recommendation
      else
        render 'new'
      end
    else
      #nutrient was not found by id, get other recommendation params and re-render 'new'
      params[:recommendation].delete(:nutrient_id)
      @recommendation = Recommendation.new(params[:recommendation])
      render 'new'
    end
  end
end
Your approach is fundamentally flawed, I'm afraid. You're not using Rails' abilities to your advantage at all.

For a simple create operation, your controller method rarely needs to be more than 10 lines or so. There's way too much going on in yours.

Start by nesting your routes:

 resources :nutrients do
   resources :recommendations
 end


Run rake routes to see how the routes now look. Basically, a recommendation will have a URL like /nutrient/:nutrient_id/recommendation/:id.

This means you'll have to make some changes to links in your views and your redirections. Where you could previously write recommendations_path and so on you'll now have to write nutrient_recommendations_path(@nutrient) and so on. Again, rake routes will show you what helpers you now have.

In your recommendation form, you'll have to do something like:

 &lt;%= form_for [@nutrient, @recommendation] %&gt;


so the form's action URL will be correct. An get rid of the hidden input that I assume you've added to the form as recommendation[nutrient_id].

Inside the RecommendationsController, you can always get the "parent" nutrient by saying

 @nutrient = Nutrient.find(params[:nutrient_id])


as that param is given in the URL.

In the end, your create method will look like

def create
  @nutrient = Nutrient.find(params[:nutrient_id])
  @recommendation = @nutrient.recommendations.new(params[:recommendation])

  if @recommendation.save
    redirect_to @recommendation, :notice =&gt; "Recommendation created."
  else
    render 'new'
  end
end


See something like this post for a more thorough diff-like walkthrough of the changes to make.

Note, that if Recommendation has further nested resources, you should use "shallow" routes, but that's left as an exercise to the reader.