简体   繁体   English

Rails 3.2更新嵌套属性

[英]Rails 3.2 Updating Nested Attributes

Here's my problem. 这是我的问题。 If I go to Projects#edit , I am unable to change the course it is assigned to. 如果我转到Projects#edit ,则无法更改其分配给的课程。 If I attempt to create a new course for it, or choose from an existing one, I get the following error: 如果尝试为其创建新课程,或从现有课程中选择,则出现以下错误:

Couldn't find Course with ID=23 for Project with ID=62
app/controllers/projects_controller.rb:49:in `update'

{...
"project"=>{"title"=>"Sup",
"due_date"=>"2012-01-23",
"course_id"=>"27",                        # THIS IS THE ID OF THE NEW COURSE I WANT
"course_attributes"=>{"name"=>"Calc I",   # THIS IS THE OLD ONE, I don't need this. Why is it passing this?
"number"=>"MATH102",
"user_id"=>"3",
"id"=>"23"},
"description"=>"bla bla bla"},
"commit"=>"Update Project",
"user_id"=>"3",
"id"=>"62"}

So I can see that it's trying to pass in the course_attributes , but it's not actually setting the new course_id . 因此,我可以看到它正在尝试传递course_attributes ,但实际上并没有设置新的course_id I don't understand why course_attributes is being passed, the other form is blank, and the course_attributes being passed, are the attributes of the old course. 我不明白为什么会传递course_attributes ,另一种形式为空白,而所传递的course_attributes是旧课程的属性。 I want to set the course_id to be the course_id being passed (27 in this case). 我想将course_id设置为要传递的course_id (在这种情况下为27)。

ProjectsController 项目控制器

def new
  @project  = @user.projects.new
  @courses = @user.courses    # Used to populate the collection_select
  @project.build_course       # I was informed I need to use this to get the form_for to work
end

def edit
  @project = Project.find(params[:id])
  @courses = @user.courses    # Used to populate the collection_select
end

def update
  @project = Project.find(params[:id])
  @courses = @user.courses

  if @project.update_attributes(params[:project])
    flash[:notice] = 'Project was successfully updated.'
    redirect_to user_projects_path(@user)
  else
    render :edit
  end
end

Line 49 is the call to update_attributes . 第49行是对update_attributes的调用。

Other Information 其他资讯

project.rb project.rb

belongs_to :user
belongs_to :course

attr_accessible :course_id, :course_attributes
accepts_nested_attributes_for :course

course.rb course.rb

belongs_to :user
has_many :projects

user.rb user.rb

has_many :projects
has_many :courses

So a project has a course_id in the database. 因此,一个项目在数据库中具有一个course_id。 I'm currently creating or choosing an existing course on the fly on the Projects#new page. 我目前正在Projects#new页面上即时创建或选择现有课程。 Here's my form for that. 这是我的表格。 I use a JavaScript toggle to alternate between the collection_select and the two text_fields. 我使用JavaScript切换按钮在collection_select和两个text_fields之间交替。

projects/new.html.haml projects / new.html.haml

= form_for [@user, @project] do |f|
  # This is shown by default
  = f.collection_select :course_id, @courses, :id, :name, { prompt: true }

  .hidden # This is hidden by default and shown using a toggle
    = f.fields_for :course do |builder|
      = builder.text_field :name, class: 'large', placeholder: 'Ex: Calculus I'
      = builder.label :number, 'Number'
      = builder.text_field :number, class: 'new_project_course_number'
      = builder.hidden_field :user_id, value: current_user.id

Now, if I am on the new project page, and I attach it to a course by choosing an existing course, it will work correctly. 现在,如果我位于新项目页面上,并且可以通过选择现有课程将其附加到课程中,那么它将可以正常工作。 The Project will be created, and the course_id will be set correctly. 将创建项目 ,并且将正确设置course_id

If I am on the new project page, and I create a course by using my JavaScript toggle, then filling out the Course Name and Course Number , and click Create, then it will also work. 如果我在新项目页面上,并且使用JavaScript切换项创建了课程,然后填写“ 课程名称”和“ 课程号” ,然后单击“创建”,那么它也将起作用。 The Course will be created, and the Project will be created with the correct course_id . 将创建课程,并使用正确的course_id创建项目

Sorry for the lengthy post, but I wanted to provide all information I could. 抱歉,冗长的帖子,但我想提供所有可能的信息。 Thanks! 谢谢!

UPDATE 1 更新1

routes.rb routes.rb

resources :users do
  resources :projects do
    collection do
      get 'completed'
      match 'course/:course_number' => 'projects#course', as: 'course'
    end
  end

  resources :courses
end

Assuming that your Projects#edit form is similiar to your Projects#new 假设您的Projects#edit表单与Projects#new类似

This is creating the course_attributes in params 这是在params中创建course_attributes

  .hidden # This is hidden by default and shown using a toggle
    = f.fields_for :course do |builder|
      = builder.text_field :name, class: 'large', placeholder: 'Ex: Calculus I'
      = builder.label :number, 'Number'
      = builder.text_field :number, class: 'new_project_course_number'
      = builder.hidden_field :user_id, value: current_user.id

That's because if a user has a current course it will create fields for every course. 这是因为如果user拥有当前课程,它将为每个课程创建字段。

If you want to be able to build a new course on the fly in edit and new change this line to: 如果您希望能够在editnew过程中快速构建新课程,请将此行更改为:

    = f.fields_for :course, @project.build_course(:user => @user) do |builder|

This will build a new course regardless of whether you're in edit or new. 无论您是编辑还是新手,这都将建立一门新course (Also you can remove @project.build_course in your controller this way.) (也可以通过这种方式在控制器中删除@project.build_course 。)

您没有列出您的路线,但是假设设置正确,那么ProjectsController更新应该能够执行以下操作:

@course = Course.find(params[:course_id])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM