Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails: Form for selecting an existing parent when creating new child records?

I have a has_many and belongs_to association set up between two models: Project and Task.

I'd like to be able to create a form which enables me to create a new Task and assign an existing Project as a parent. For example, this form might have a pulldown for selecting from a list of existing projects.

There are only a finite set of projects available in this application, so I've created Project records via a seeds.rb file. I do not need to make a form for creating new Projects.

I believe I've achieved a solution by using a collection_select form helper tag in the new Task form. I'm pretty happy with how this works now, but just curious if there are other approaches to this problem.

#models/project.rb
class Project < ActiveRecord::Base
  has_many :tasks, :dependent => :destroy
end

#models/task.rb
class Task < ActiveRecord::Base
  belongs_to :project
end

#controllers/tasks_controller.rb
class TasksController < ApplicationController

  def new
    @task = Task.new

    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render :xml => @task }
    end
  end

  def create
    @task = Task.new(params[:task])

    respond_to do |format|
      if @task.save
        format.html { redirect_to(@task, :notice => 'Task was successfully created.') }
        format.xml  { render :xml => @task, :status => :created, :location => @task }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @task.errors, :status => :unprocessable_entity }
      end
    end
  end
end

#views/new.html.erb
<h1>New task</h1>

<%= form_for(@task) do |f| %>
  <div class="field">
    <%= f.label :name %><br />
    <%= f.text_field :name %>
  </div>
  <div class="select">
    <%= collection_select(:task, :project_id, Project.all, :id, :name) %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

<%= link_to 'Back', tasks_path %>
like image 982
Chanpory Avatar asked Dec 07 '10 18:12

Chanpory


2 Answers

I just reviewed your code and this looks fantastic to me. One small tweak:

<%= f.collection_select(:project_id, Project.all, :id, :name) %>

This is just slightly cleaner in that you're still using the |f| block variable

like image 82
efalcao Avatar answered Sep 28 '22 19:09

efalcao


Since you mentioned other approaches, I would definitely mention and actually recommend, you use formtastic. The associations are handled automatically and keeps your code clean and also gives you some great customization options.

like image 42
Shreyas Avatar answered Sep 28 '22 19:09

Shreyas