1

コードをクリーンアップしたところ、見栄えが良くなりましたが、まだ機能しません。それは苦痛になり始めます…</p>

親 has_many childs :through joinmodel を使用してネストされた形式で既存の子を持つ親を保存することはできません。

私の場合、プロジェクトには多くの貢献する教師と多くの貢献する生徒がいて、どちらもユーザーへの参加モデルです。プロジェクトには、学校もたくさんあります。

(モデルの名前は、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+ ネストされたフォームの問題: 保護された属性を一括割り当てできない

accept_nested_attributes_for と has_and_belongs_to_many を使用しようとしていますが、結合テーブルにデータが入力されていません

引用: 「accepts_nested_fields_for は、フォーム内の関連オブジェクトを作成および変更するために使用されます。結合テーブルにデータを入力するために使用できます。これは、あなたがやろうとしていることのようなものです。ただし、accepts_nested_fields_for を使用して結合テーブルに入力することは、HABTM 関係では不可能です。」</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