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.
I know this is old, but "people" is already plural, so it should be
belongs_to :people
has_many :people
etc..
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)
精彩评论