我有几个小时的事情可能很容易。
我有一个嵌套模型
resources :grades do
resources :students
end
所以我定义了
before_action :set_grade, except: [:mass_input]
到我的students_controller
def set_grade
@grade = Grade.find(params[:grade_id])
end
我对此很好,问题是现在我正在使用另一个操作:来自其他来源的grade_id,所以我不能使用set_grade,而是我用javascript传递id。的工作原理。
我的问题出现在这里,当我尝试调用create方法时,我可能做错了..
def mass_input
@grade = Grade.find(@data['grade'])
@data = JSON.parse(params[:form_data])
#is this create way ok or I'm overriding???
Student.create(:rut => @data['mass_students'][1][0], :nombre => @data['mass_students'][1][1], :apellido => @data['mass_students'][1][2])
end
这是我的创建动作
def create
@student = Student.new(student_params)
@grade.students << @student
respond_to do |format|
if @student.save
format.html { redirect_to school_grade_path(@grade.school,@grade), notice: 'Alumno creado con éxito.' }
format.json { render :show, status: :created, location: @student }
else
format.html { render :new }
format.json { render json: @student.errors, status: :unprocessable_entity }
end
end
end
通过这种方式代码可以工作,但这行不起作用
@grade.students << @student
@grade没有从mass_input传递给create。我想我并没有正确地调用create,但是我找不到怎么做,因为它不会重定向
我的mass_input行动正在以这种方式运作
def mass_input
@grade = Grade.find(@data['grade'])
@data = JSON.parse(params[:form_data])
Student.create(:rut => @data['mass_students'][1][0], :nombre => @data['mass_students'][1][1], :apellido => @data['mass_students'][1][2])
grade.students << student
respond_to do |format|
if student.save
format.html { redirect_to school_grade_path(grade.school,grade), notice: 'Alumno creado con éxito.' }
format.json { render :show, status: :created, location: student }
else
format.html { render :new }
format.json { render json: student.errors, status: :unprocessable_entity }
end
end
end
但我认为是AWFUL,我必须使用自己的创建动作
谢谢!
答案 0 :(得分:0)
哦......从我的观点来看,你做的很奇怪...你的问题的快速解决方案就像这样:
1)以新的方式重写行动:
before_action :set_grade
方法set_grade:
def set_grade
@grade = Grade.find(params[:grade_id].presence || @data['grade'])
end
2)设置学生参数的方法
def student_params
data = JSON.parse(params[:form_data])['mass_students']
#Transform data to be student params. For ex:
data.map{|_key, info| {:rut => info[0], :nombre => info[1], :apellido => info[2]}}
end
3)重写mass_input方法
def mass_input
respond_to do |format|
if (@students = @grade.students.create(student_params).all?(&:persisted?)
#some actions when everything is great.
else
#some actions if not of them valid (maybe redirect & show info about not created students)
end
end
end
但你应该明确阅读更多的导轨... http://guides.rubyonrails.org/
答案 1 :(得分:0)
对不起,我无法发表评论。所以我可以发一个回复,但这不是一个完整的答案。在学生控制器中 尝试使用
<div class="foo bar1"></div>
<div class="foo bar2"></div>
<script type="text/javascript">
$(".foo").each(function () {
console.log(this); //logs <div class="foo...
});
$(".foo").on("click", function () {
console.log(this); //logs <div class="foo...
});
$(".foo").each(function () {
this.click();
});
</script>
或
@student = @grade.students.new
所以当你做@ student.save时,你不需要做下面这一行,它仍然有用
@student = Student.new
@student.grade = @grade or @student.grade_id = params[:grade_id]
答案 2 :(得分:0)
Ruby on rails具有您应遵循的约定,以简化许多事情。我在这里看到的第一件事就是在def mass_input
,你正在使用
Student.create(...)
方法create
,正如它所说,创建了一个对象,但也将其保存到数据库中。所以你应该new
而不是create
,因为new
没有将它保存到数据库,只是实例化它:
@student = Student.new
...在def mass_input
内,默认情况下,视图中的提交操作会将您的对象带到create方法(如果对象是新的,则会创建,其他方式更新,感谢Rails的)。为此,您可以查看http://guides.rubyonrails.org/action_controller_overview.html
关于第@grade.students << @student
行,我假设您打算将新创建的学生添加到他的成绩中。在尝试创建,编辑或销毁http://railscasts.com/episodes/139-nested-resources时,请参阅此嵌套资源的使用示例。无论如何,嵌套资源意味着:
class Grade < ActiveRecord::Base
has_many :student
end
class Student < ActiveRecord::Base
belongs_to :grade
end
因此,在您的模型Student
中,您应该有一个列来存储该学生的Grade
。然后在您的参数中,您应该会收到实际成绩并将其存储在grade_id
内的@student
中。
如果问题不明确,建议您查看嵌套资源指南http://guides.rubyonrails.org/routing.html#nested-resources
作为评论,<<
用于将“事物”添加到数组的末尾,即如果您想快速存储数组中使用的某些信息:
array = []
Student.all.each do |s|
array << s.name
end
它将存储在array
学生的所有名字中。显然有一种更简单的方法可以做到这一点:
Student.pluck(:name)