1

我清理了我的代码,现在看起来好多了,但仍然无法正常工作。开始很痛苦……</p>

我只是无法以嵌套形式保存具有现有子级的父级与父级 has_many 子级:通过连接模型。

在我的例子中,一个项目 has_many 贡献的教师和许多贡献的学生,两者都是用户的加入模型。一个项目也有很多学校。

(也许我应该更好地将模型命名为 Teacherize 和 Pupilize 或 ProjectTeacher 和 ProjectPupil。)

只要所有记录都是新的,它就可以正常工作。一旦我想将现有用户连接为新项目的新教师,我就会收到以下错误:

Couldn't find User with ID=1 for Teacher with ID= (1 是正确的用户 ID)

问题应该是她在我的助手中设置空表单字段的地方:

至少我猜是这样...

module ProjectsHelper
  def setup_project(project)
    if project.teachers.length <= 0  # usually there is just one teacher, so add one if there isn't one
      teacher = project.teachers.build(:role_in_project => 'master')
      if user_signed_in?
        #teacher = project.teachers.new(:role_in_project => 'master', :user => current_user)
        teacher.user = current_user # associate first teacher with current_user
      else
        #teacher = project.teachers.build
        teacher.user = User.new   # associate first teacher with a new user instance
      end
    end
    if project.project_schools.length <= 0   # usually there is just one school, so add one if there isn't one
      project_school = project.project_schools.build
      project_school.school = School.new
    end
    if project.pupils.length < 3  # There can be up to 3 people, so add a blank fieldset as long as there are less than 3
      pupil = project.pupils.build
      pupil.user = User.new
    end
    project
  end
end

这些是我收到的参数:

    {"utf8"=>"✓", "authenticity_token"=>"uCCMk/s3SpDfR7+fXcsCOHPvfvivBQv8pVFVhdh6iro=", 
     "project"=>{
       "teachers_attributes"=>{
           "0"=>{
                 "id"=>"",
                 "user_attributes"=>{
                      "id"=>"1",
                      "gender"=>"male",
                      "title"=>"",
                      "firstname"=>"Firstname1",
                      "name"=>"Lastname1",
                      "faculty"=>"",
                      "fon"=>"",
                      "fax"=>""}
                 }
           }, 
           "id"=>"",
           "title"=>"First Project",
           "description"=>"This is a foo bar project!",
           "presentation_type"=>"experimentell",
           "note"=>""
      }, 
      "commit"=>"Register Project",
      "action"=>"create",
      "controller"=>"projects"
   }

案例不是太抽象;必须有可能实现它。只是将新的父记录与现有的子记录连接起来!

在这篇非常好的文章中,确切地解释了这种情况: http: //rubysource.com/complex-rails-forms-with-nested-attributes

# app/helpers/form_helper
module FormHelper
  def setup_user(user)
    user.address ||= Address.new
    (Interest.all - user.interests).each do |interest|
      user.interest_users.build(:interest => interest)
    end
    user.interest_users.sort_by! {|x| x.interest.name }
    user/tmp/clean-controllers.md.html
  end
end

那里的兴趣是存在的,并通过interest_uesers 中的新记录连接起来。

为什么我在尝试做同样的事情时会收到错误消息?

project.teachers.build(:user => current_user)

我研究了几篇文章和演员表,但没有一篇将现有的孩子联系起来。 http://railscasts.com/episodes/196-nested-model-form-revised http://apidock.com/rails/ActionView/Helpers/FormHelper/fields_for http://api.rubyonrails.org/classes/ActiveRecord/ NestedAttributes/ClassMethods.html Rails 3.1+ 嵌套表单问题:无法批量分配受保护的属性

尝试使用 Accepts_nested_attributes_for 和 has_and_belongs_to_many 但未填充连接表

Quote: “accepts_nested_fields_for 用于创建和修改表单中的相关对象。它可用于填充连接表,这正是您想要做的。但是,对于 HABTM 关系,使用accepts_nested_fields_for 填充连接表是不可能的。”</p>

这就是我想做的!填充连接表! 它开始令人沮丧,我很乐意得到一些帮助!


我的模特

class Project < ActiveRecord::Base
  attr_accessible :title, :description, :presentation_type, :note,
                  :project_schools_attributes, :schools_attributes, :teachers_attributes, :pupils_attributes,
                  :users_attributes


  validates_presence_of :title
  validates_presence_of :description
  validates_presence_of :presentation_type


  has_many :project_schools,                :dependent => :destroy
  accepts_nested_attributes_for :project_schools
  has_many :schools,                        :through => :project_schools
  #accepts_nested_attributes_for :schools,   :reject_if => :all_blank

  has_many :pupils,                         :dependent => :destroy
  accepts_nested_attributes_for :pupils,    :reject_if => :all_blank
  has_many :users,                          :through => :pupils

  has_many :teachers,                       :dependent => :destroy
  accepts_nested_attributes_for :teachers,  :reject_if => :all_blank

  has_many :users,                          :through => :teachers
  #accepts_nested_attributes_for :users,    :reject_if => :all_blank
end

class ProjectSchool < ActiveRecord::Base
  attr_accessible :role_in_project, :comment,
                  :school_attributes, :school_id, :project_id

  belongs_to :school
  accepts_nested_attributes_for :school
  belongs_to :project
end

class School < ActiveRecord::Base
  attr_accessible :email, :fax, :fon, :name, :place, :street, :type_of_school, :www, :zip

  has_many :project_schools
  has_many :projects, :through => :project_schools
  has_many :users # in real live they are named teachers and pupils but in this case the association goes directly to a user_id, not to teacher/pupil model


  validates_presence_of :name, :type_of_school, :street, :place, :zip, :fon
  validates :email, :format => { :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i, :on => :create }, :allow_blank => true
end

class Teacher < ActiveRecord::Base
  attr_accessible :role_in_project, :user, :user_attributes, :project_id, :user_id

  belongs_to :project
  belongs_to :user
  accepts_nested_attributes_for :user

  serialize :role_in_project
end

class Pupil < ActiveRecord::Base
  attr_accessible :classname, :user_attributes #, :project_id, :user_id

  belongs_to :project
  belongs_to :user
  accepts_nested_attributes_for :user
end

class User < ActiveRecord::Base
  serialize :roles

  belongs_to :school
  has_many :teachers
  has_many :pupils
  has_many :projects, :through => :teachers
  has_many :projects, :through => :pupils

  # Setup accessible (or protected) attributes for your model
  attr_accessible :email, :gender, :firstname, :name, :street, :place, :title, :faculty, :assignment,
                  :classname, :zip, :fon, :fax, :school_id, :roles,
                  :password, :added_by_user_id, :password_confirmation, :remember_me

  # Include default devise modules. Others available are:
  # :token_authenticatable, :confirmable,
  # :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable#, :validatable

  after_initialize :init
  def init
    # the default guest user
    self.roles  ||= ['default']           #will set the default value only if it's nil
  end
end

我的控制器

class ProjectsController < ApplicationController
  require 'axlsx'
  before_filter :load_page, only: [:show, :index, :destroy]

  def new
    @project = Project.new
  end

  def create
    @project = Project.new(params[:project])

    respond_to do |format|
      if @project.save
        sign_in(:user, @project.teachers[0].user) unless user_signed_in?

        # TODO: send mail

        # save as excel file in dropbox
        save_in_dropbox(@project)

        format.html { redirect_to @project, notice: t('project.was_created') }
      else
        logger.debug @project.errors.inspect
        format.html { render action: "new" }
      end
    end
  end
end

项目/_form.html.haml

%h1
  = t('project.register_headline')
= simple_form_for( setup_project(@project), :html => {:class => 'form-horizontal'} )do |f|
  = f.error_notification
  #teachers-wrapper.well
    %span.jumpanchor#lehrkraft_anchor
    %fieldset.form-inputs
      = f.simple_fields_for :teachers do |teacher|
        = render "teacher_fields", :f => teacher


  .school-wrapper.well
    %span.jumpanchor#schule_anchor
    %h2
      Informationen zur Schule
    %fieldset.form-inputs
      = f.simple_fields_for :project_schools do |project_school|
        = render "school_fields", :f => project_school
  .project-wrapper.well
    %span.jumpanchor#projekt_anchor
    %h2
      Informationen zum Projekt der Schüler
    %fieldset.form-inputs
      = f.hidden_field :id
      = f.input :title, :input_html => { :class => 'span6' }
      = f.input :description, :input_html => { :class => 'span6', rows: 5 }
      = f.input :presentation_type, collection: ['theoretisch', 'experimentell'], as: :radio_buttons, :class => 'controls-row', :input_html => { :class => 'inline' }
      .clearfix
      = f.input :note, :input_html => { :class => 'span6', rows: 3 }
  .pupils-wrapper.well
    %span.jumpanchor#schuler_anchor
    %fieldset.form-inputs
      = f.simple_fields_for :pupils do |pupil|
        = render "pupil_fields", :f => pupil

projects/_teacher_fields.html.haml
= f.simple_fields_for :user do |user|
  =# render "teacher_user_fields", :f => user
  %h2
    Betreuende Lehrkraft
  - if user_signed_in?
    = user.input :email, :disabled => true, :input_html => {:class => 'email_validation'}
  - else
    = user.input :email, :autofocus => true, :input_html => {:class => 'email_validation'}, :hint => 'Dies muß Ihre eigene E-Mailadresse sein!'
  .details
    =# user.hidden_field :id
    = user.input :id
    = user.input :gender, collection: [:female, :male]
    = user.input :title
    = user.input :firstname
    = user.input :name
    = user.input :faculty
    = user.input :fon
    = user.input :fax

它是带有 Ruby 1.9.3 的 Rails 3.2

4

0 回答 0