我想知道是否有人能够帮助我弄清楚为什么这不起作用。
我有一个模型让我们称它为属于项目模型的任务。我基本上希望每个任务在每个项目中都有一个唯一的名称(Project1
可以有一个名为task1
的任务,因此Project2
可以只有一个名为task1
的任务。这似乎是:scope选项的用途,但它似乎并不适合我。
任务模型是项目中的嵌套资源,因此我通过project_tasks_path(@project)
调用创建操作。它可以很好地创建任务并将它们分配给项目,但唯一性验证的范围并未实现。如果我在task1
中创建任务Project1
,我无法在任务2中创建一个具有相同名称的任务。
这是我的设置:
Task.rb
class Task < ActiveRecord::Base
belongs_to :project
validates :name, presence: true, uniqueness: {scope: :project_id}
tasks_controller.rb
def create
@project = Project.find_by(id: params[:project_id])
@task = Task.new(model_params)
#print task to stdout
puts "@task"
ap @task
respond_to do |format|
if @task.save
flash[:notice] = "Successfully created task"
format.js
else
# no flash as form handles errors
format.js { render action: 'new' }
format.html { render action: 'new' }
end
end
end
由于某种原因,当我输出新创建的任务的内容时,我得到以下
#<Task:0x007ff7c7c3b178> {
:id => nil,
:name => "test",
:project_id => nil,
:created_at => nil,
:updated_at => nil
}
似乎因为project_id目前尚未设置,所以它使用的是“nil”。作为价值。
解决这个问题的最佳方法是什么?它只是一个自定义验证器吗?
修改1
def model_params
params.require(:model).permit(:name, :project_id)
end
答案 0 :(得分:0)
是的,一直在玩这个,似乎进行这种验证的方式非常简单。它需要的是嵌套资源是根据它的项目构建的,这会强制:parent_id按预期传递给验证。
对于这个玩具示例,这意味着创建动作必须类似于:
@project = Project.find_by(id: params[:project_id])
@task = @project.tasks.build(model_params)
应该注意的是,由于Rails不支持从命令行生成嵌套资源,脚手架生成控制器处理创建的方式是Model.new(model_params)
然后保存,这似乎没有提升:parent_id
及时进行验证,因此需要如上所述进行更改(就父级而言)。