0

In my rails app I have the following models

class Member < ActiveRecord::Base
  has_many :trainings
end

class Student < ActiveRecord::Base
  belongs_to :member
  has_many :trainings   #maybe a through relationship here
end

class Teacher < ActiveRecord::Base
  belongs_to :member
end

######edited#################

class Training < ActiveRecord::Base
  belongs_to :member  #only member not student nor teacher
end

#############################

Now, how can I build the trainings in my student controller

class StudentsController < ApplicationController
  def new
    @student = Student.new
    @student.trainings.build    #### This is not working
  end
end

Thanks

Tiamon
  • 217
  • 2
  • 12

2 Answers2

0

You have to write accepts_nested_attributes_for in the model and add them in strong parameters if you are using rails 4. Like this :

class Student < ActiveRecord::Base
  belongs_to :member
  has_many :trainings     
  accepts_nested_attributes_for :trainings
end

class StudentsController < ApplicationController
  def new
    @student = Student.new
    @student.trainings.build 
  end

  def create
    @student = Student.create(student_params)
    @student.trainings.build(params[:student][:trainings])

    redirect_to student_path
  end

  #For rails 4

  def student_params
     params.require(:student).permit(:id, :name, trainings_attributes: [ :id, :your fields here ])
    end
end

Here is a link that will help you: Rails 4: accepts_nested_attributes_for and mass assignment

Community
  • 1
  • 1
  • Their issue has nothing to do `accepts_nested_attributes_for`, at the moment; rather, they cannot build a scoped instance of `Training`. – Jordan Allan Feb 07 '15 at 08:33
  • Thanks for your Answer. The problem here is i prefer not to have both (student_id and teacher_id) columns on trainig. I prefer only member_id instead. I hope it is clear now – Tiamon Feb 07 '15 at 08:44
  • BTW I have accepts_nested_attributes and using strong params – Tiamon Feb 07 '15 at 08:45
0

If you've properly defined your associations, then the code in your new controller action will work (I tested it). Check and make sure your Training model exists, or that you've used the correct association name (perhaps you meant :teachers?).

app/models/student.rb

class Student < ActiveRecord::Base
  has_many :trainings
end

app/models/training.rb

class Training < ActiveRecord::Base
  belongs_to :student
end

app/controllers/students_controller.rb

class StudentsController < ApplicationController
  def new
    @student = Student.new
    @student.trainings.build
  end
end

Update:

Assuming these are how your associations are defined, you could build a scoped instance of Training like so:

app/models/member.rb

class Member < ActiveRecord::Base
  has_many :trainings
end

app/models/student.rb

class Student < ActiveRecord::Base
  delegate :trainings, to: :member
  belongs_to :member
end

app/models/training.rb

class Training < ActiveRecord::Base
  belongs_to :member
end

app/controllers/students_controller.rb

class StudentsController < ApplicationController
  def new
    @student = Student.new
    @student.build_member
    @student.trainings.build
  end
end

Hope that helps.

Jordan Allan
  • 4,224
  • 7
  • 28
  • 34
  • I want model training to belong_to model not student. Is that possible? – Tiamon Feb 07 '15 at 08:43
  • can you please clarify? you want `training` to `belong_to` which model? – Jordan Allan Feb 07 '15 at 08:45
  • Please check it again, I have edited it. I want it to belong to member – Tiamon Feb 07 '15 at 08:48
  • Since `trainings` exists on `member`, you'll need to build a scoped instance of `member` before you can build a `training`. Defining `delegate :trainings, to: :member` on the `Student` model allows you to build a scoped instance of `Training` through `student.trainings.build`. – Jordan Allan Feb 07 '15 at 09:24