我有一个嵌套模型,Task属于Project,所以在我的模型中:
class Task < ActiveRecord::Base
belongs_to :project
validates :project_id, :presence => true
在我的项目模型中,我有:
class Project < ActiveRecord::Base
has_many :tasks, :dependent => :destroy
现在,我有一个表单来创建一个新任务,用户可以在其中指定project_id,即任务所属的项目。所以我的表格看起来像这样:
<%= form_for [@project, @task], :remote => true do |f| %>
<%= f.label :title, "Title" %>
<%= f.text_field :title %>
<%= label_tag("Project") %>
<%= select(nil, :project_id, (get_active_projects).collect {|p| [p.title, p.id] }, {:prompt => 'Select Project'}) %>
<%= f.label :description %>
<%= f.text_area :description %>
<div class="actions">
<%= f.submit 'Save' %>
</div>
<% end %>
我在验证时遇到的问题是,如果用户没有在表单中选择项目(project_id),我会收到一条错误,说明在进行任何验证之前无法找到项目吗?我希望我的验证强制执行project_id,以便在尝试查找项目之前发生。
def create
@project = Project.find(params[:project_id])
@task = @project.tasks.new(params[:task])
@task.update_attributes(:status_id => 2)
@task.save!
答案 0 :(得分:1)
按照自己的方式尝试在方法中查找项目,如果project_id为nil,则会出现错误。因为它是has_many和belongs_to关系,它足以在任务中保存project_id,您不必通过项目创建任务。由于您创建的任务不多,因此您不需要在form_中使用项目对象,因为您可以像这样
<%= form_for @task, :remote => true do |f| %>
<%= error_messages_for(@task) %>
<%= f.label :title, "Title" %>
<%= f.text_field :title %>
<%= f.label :project_id %>
<%= f.select(nil, :project_id, (get_active_projects).collect {|p| [p.title, p.id] }, {:prompt => 'Select Project'}) %> (just check the select syntax if i did something wrong)
<%= f.label :description %>
<%= f.text_area :description %>
<div class="actions">
<%= f.submit 'Save' %>
</div>
<% end %>
然后在你的控制器方法中应该像这个一样简单
def create
params[:task][:status_id] = 2
@task = Task.new(params[:task])
if @task.save!
what you want to do if valid
else
go back to same page with errors
end
end