1

I have simple project+task application I am creating in Rails 3.1.RC4. It will have project names, tasks and each task will be assigned to a person. The project form is simple with only two boxes (1) task name and (2) the tasks and assignee. On the backend, I would like to parse the tasks and assignees and put them all into the right models.

Sample Input

Project Name: Birthday Party for Pip

Task, assignee:

  • Clean bathroom, John
  • Shine shoes, Sally
  • Bake cake, Peter
  • Buy champagne, Susan

It has four models:

    class Project < ActiveRecord::Base
      has_many :tasks
      has_many :assignments, :through => :tasks
      has_many :people, :through => :assignments
      attr_writer :task_text
      after_save :assign_tasks
    
      def task_text
        @task_text || tasks.map(&:name).join(' ')
      end
    
      private
    
      def assign_tasks
        if @task_text
          self.tasks = @task_text.split(/\n/).map do |line|
            assignment = line.split(',').first
            assignee = line.split(',').last
            Task.find_or_create_by_name(assignment)
            Task.people.find_or_create_by_name(assignee)
          end
        end
      end
    end
    
    class Task < ActiveRecord::Base
      attr_accessible :name
      belongs_to :project
      has_many :assignments
      has_many :peoples, :through => :assignments
    end
    
    class Assignment < ActiveRecord::Base
      belongs_to :tasks
      belongs_to :peoples
    end
    
    class People < ActiveRecord::Base
      has_many :assignments
      has_many :tasks, :through => :assignments
    end
    

Here is the one form partial:

    <%= form_for @project do |f| %>
      <%= f.error_messages %>
      <p>
        <%= f.label :name %><br />
        <%= f.text_field :name %>
      </p>
      <p>
        <%= f.label :task_text, "Tasks, assignees" %><br />
        <%= f.text_area :task_text %>
      </p>
      <p><%= f.submit %></p>
    <% end %>
    

Right now I am getting an undefined method error for "people".

I have reviewed Railscasts covering many-to-many models, virtual attributes and nested models, but I have not been able to make the leap. I must accomplish this task without Javascript.

Community
  • 1
  • 1
JHo
  • 1,068
  • 1
  • 14
  • 29

2 Answers2

1

I know this is old, but "people" is already plural, so it should be

belongs_to :people
has_many :people

etc..

hmind
  • 840
  • 1
  • 6
  • 15
0

Maybe just

task = Task.find_or_create_by_name(assignment)
task.peoples.find_or_create_by_name(assignee)
task

insead of

Task.find_or_create_by_name(assignment)
Task.people.find_or_create_by_name(assignee)
marc
  • 6,103
  • 1
  • 28
  • 33
  • Thanks for that. I implemented it and got a new error `NameError in ProjectsController#create` `uninitialized constant Task::Peoples` – JHo Jul 23 '11 at 19:06