我正在创建一个应用,学生可以点击复选框说他们已经上过课。我尝试使用ajax调用来执行此操作,并实时更新同一页面。到目前为止,我能够在数据库中正确获取信息,但我有两个错误。一个错误是学生的名字在视图上显示两次(在硬刷新之后),第二个是代码没有在页面上实时显示结果。我该如何解决这些错误?我非常感谢任何帮助,我已经坚持了一段时间。这是我到目前为止的代码......
lecture.html.erb(查看页面,讲座显示页面)
<h1>Lecture Profile</h1>
<h3><%= @lecture.name %></h3>
<p>Start Time: <%= @lecture.start_time %></p>
<p>End Time: <%= @lecture.end_time %></p>
<p>Notes: <%= @lecture.notes %></p>
<div>
<p><%= link_to "Edit Lecture", "/lectures/#{@lecture.id}/edit" %></p>
<p><%= link_to "Delete Lecture", "/lectures/#{@lecture.id}", method: :delete, data:{confirm: "Are you sure you want to delete this lecture"} %></p>
</div><br>
<%= form_for @attendance, remote: true do |f| %>
<%= render partial: "/attendances/form", locals: {f: f} %>
<%= f.hidden_field :arrived, value: Time.now %>
<%= f.hidden_field :student_id, value: current_student.id %>
<%= f.hidden_field :lecture_id, value: @lecture.id %>
<%= submit_tag "Submit" %>
<% end %>
<h2>Students Attended</h2>
<%= render partial: "/attendances/index", locals:{attendances: @attendances}%>
_form.html.erb(新出席的表格)
<div id="attended-checkbox">
<%= f.label current_student.friendly_name %>
<%= f.label :attended %>
<%= f.check_box :attended %>
</div>
_index.html.erb(查看用于展示参加过该课程的学生的模板)
<div class="lectures-attended-students" id="attendance_<%= @attendance.id %>">
<% @attendances.each do |attendance| %>
<% attendance.lecture.cohort.students.each do |student| %>
<% student.attendances.each do |a|%>
<% if a.attended == true %>
<p><%= student.friendly_name %></p>
<% end %>
<% end %>
<% end %>
<% end %>
</div>
考勤控制员
class AttendancesController < ApplicationController
def new
end
def create
@attendance = Attendance.new(attendance_params)
@lecture = Lecture.find_by(id: params[:id])
respond_to do |format|
if @attendance.save
format.html { redirect_to '/lectures/@lecture.id', notice: 'Attendance was successfully created.' }
format.json { render :show, status: :created, location: @attendance }
format.js
else
format.html { render :new }
format.json { render json: @attendance.errors, status: :unprocessable_entity }
format.js
end
end
end
private
def attendance_params
params.require(:attendance).permit(
:arrived,
:attended,
:lecture_id,
:student_id
)
end
end
讲座控制员
class LecturesController < ApplicationController
def new
@lecture = Lecture.new
@cohort = Cohort.find_by(id: params[:id])
end
def create
@lecture = Lecture.new(lecture_params)
if @lecture.save
flash[:success] = "Successfully created new lecture"
redirect_to "/cohorts/#{@lecture.cohort_id}"
else
flash[:warning] = "Lecture Not Created"
render :new
end
end
def show
@lecture = Lecture.find_by(id: params[:id])
@attendance = Attendance.new
@attendances = Attendance.all
end
def edit
@lecture = Lecture.find_by(id: params[:id])
end
def update
@lecture = Lecture.find_by(id: params[:id])
if @lecture.update(lecture_params)
flash[:success] = "Successfully updated lecture"
redirect_to "/cohorts/#{@lecture.cohort_id}"
else
flash[:warning] = "Lecture Not Updated"
render :edit
end
end
def destroy
@lecture = Lecture.find_by(id: params[:id])
cohort_id = @lecture.cohort_id
@lecture.destroy
flash[:success] = "Your lecture has been deleted"
redirect_to "/cohorts/#{cohort_id}"
end
private
def lecture_params
params.require(:lecture).permit(
:name,
:start_time,
:end_time,
:notes,
:cohort_id
)
end
end
create.js.erb
$("#attended-checkbox").val('');
$(".lectures-attended-students").prepend('<%= j render @attendance');
选中此框并单击提交按钮后,终端将返回此错误
attendances/create.js.erb:7: syntax error, unexpected tSTRING_BEG, expecting keyword_do or '{' or '('
...$(".lectures-attended-students").prepend(\''.freeze;@output_...
单击视图页面上的刷新按钮后,终端显示此
Started GET "/lectures/1" for ::1 at 2016-08-25 11:50:33 -0500
Processing by LecturesController#show as HTML
Parameters: {"id"=>"1"}
Lecture Load (1.0ms) SELECT "lectures".* FROM "lectures" WHERE "lectures"."id" = $1 LIMIT 1 [["id", 1]]
Student Load (0.4ms) SELECT "students".* FROM "students" WHERE "students"."id" = $1 LIMIT 1 [["id", 5]]
Rendered attendances/_form.html.erb (8.0ms)
Attendance Load (0.7ms) SELECT "attendances".* FROM "attendances"
Lecture Load (0.3ms) SELECT "lectures".* FROM "lectures" WHERE "lectures"."id" = $1 LIMIT 1 [["id", 1]]
Cohort Load (0.3ms) SELECT "cohorts".* FROM "cohorts" WHERE "cohorts"."id" = $1 LIMIT 1 [["id", 5]]
Student Load (0.3ms) SELECT "students".* FROM "students" WHERE "students"."cohort_id" = $1 [["cohort_id", 5]]
Attendance Load (0.3ms) SELECT "attendances".* FROM "attendances" WHERE "attendances"."student_id" = $1 [["student_id", 5]]
Attendance Load (0.3ms) SELECT "attendances".* FROM "attendances" WHERE "attendances"."student_id" = $1 [["student_id", 7]]
CACHE (0.0ms) SELECT "lectures".* FROM "lectures" WHERE "lectures"."id" = $1 LIMIT 1 [["id", 1]]
CACHE (0.1ms) SELECT "cohorts".* FROM "cohorts" WHERE "cohorts"."id" = $1 LIMIT 1 [["id", 5]]
CACHE (0.0ms) SELECT "students".* FROM "students" WHERE "students"."cohort_id" = $1 [["cohort_id", 5]]
CACHE (0.0ms) SELECT "attendances".* FROM "attendances" WHERE "attendances"."student_id" = $1 [["student_id", 5]]
CACHE (0.0ms) SELECT "attendances".* FROM "attendances" WHERE "attendances"."student_id" = $1 [["student_id", 7]]
Rendered attendances/_index.html.erb (25.2ms)
Rendered lectures/show.html.erb within layouts/application (52.1ms)
Completed 200 OK in 311ms (Views: 290.8ms | ActiveRecord: 3.8ms)
提交前的视图(测试测试是学生的名字)
Lecture Profile
Routing
Start Time: 2016-08-31 18:00:00 UTC
End Time: 2016-08-31 21:30:00 UTC
Notes: Intro to Rails routing.
Edit Lecture
Delete Lecture
Test test Attended
Submit
Students Attended
Test45 Test45
本地主机帖子提交和硬刷新的实际显示。 (显示三个名称,而不是一个新名称。这包括先前提交的名称,以及新名称两次)
Lecture Profile
Routing
Start Time: 2016-08-31 18:00:00 UTC
End Time: 2016-08-31 21:30:00 UTC
Notes: Intro to Rails routing.
Edit Lecture
Delete Lecture
Test test Attended
Submit
Students Attended
Test Test
Test45 Test45
Test Test
Test45 Test45
编辑:--------------------------------------------- ------------------------
这些更改修复了硬刷新中的重复数据错误,但现在我正在处理ajax请求的nil类错误。我不明白我是怎么不通过讲座的。
讲座.rb(将演讲模式改为此)
class Lecture < ActiveRecord::Base
belongs_to :cohort
has_many :attendances
has_many :attended_students, through: :attendances, source: :student
end
_attendance.html.erb(更改为此内容)
<div class="lectures-attended-students" id="attendance_<%= @attendance.id %>">
<% @lecture.attended_students.each do |student| %>
<p><%= student.friendly_name %></p>
<% end %>
</div>
show.html.erb(Lectures Show Page现在看起来像这样)
<h1>Lecture Profile</h1>
<h3><%= @lecture.name %></h3>
<p>Start Time: <%= @lecture.start_time %></p>
<p>End Time: <%= @lecture.end_time %></p>
<p>Notes: <%= @lecture.notes %></p>
<div>
<p><%= link_to "Edit Lecture", "/lectures/#{@lecture.id}/edit" %></p>
<p><%= link_to "Delete Lecture", "/lectures/#{@lecture.id}", method: :delete, data:{confirm: "Are you sure you want to delete this lecture"} %></p>
</div><br>
<%= form_for @attendance, remote: true do |f| %>
<%= render partial: "/attendances/form", locals: {f: f} %>
<%= f.hidden_field :arrived, value: Time.now %>
<%= f.hidden_field :student_id, value: current_student.id %>
<%= f.hidden_field :lecture_id, value: @lecture.id %>
<%= submit_tag "Submit" %>
<% end %>
<h2>Students Attended</h2>
<%= render partial: @attendance, locals:{lecture: @lecture}%>
create.js.erb(现在看起来像这样)
$("#attended-checkbox").val('');
$(".lectures-attended-students").prepend('<%= j render @attendance, locals:{lecture: @lecture} %>');
这是终端给我的东西
Completed 500 Internal Server Error in 42ms (ActiveRecord: 9.4ms)
ActionView::Template::Error (undefined method `attended_students' for nil:NilClass):
1: <div class="lectures-attended-students" id="attendance_<%= @attendance.id %>">
2: <% @lecture.attended_students.each do |student| %>
3: <p><%= student.friendly_name %></p>
4: <% end %>
5: </div>
app/views/attendances/_attendance.html.erb:2:in `_app_views_attendances__attendance_html_erb__505249290825397873_70333903626520'
app/views/attendances/create.js.erb:3:in `_app_views_attendances_create_js_erb__3555789531505990218_70333854235700'
app/controllers/attendances_controller.rb:11:in `create'
答案 0 :(得分:0)
我相信你的问题可能就在这里:
<% @attendances.each do |attendance| %>
<% attendance.lecture.cohort.students.each do |student| %>
<% student.attendances.each do |a|%>
<% if a.attended == true %>
<p><%= student.friendly_name %></p>
<% end %>
<% end %>
<% end %>
<% end %>
您正在查询所有出席情况,并在每个出席情况中进行迭代,然后再回到学生的出席情况。每次出席时,您都会打印所有参加考试的学生。在这种情况下,您有2个参加者,因此每个学生有2个参赛作品。具有这种活动记录查询的嵌套循环可能很麻烦,并且是不好的做法,因为它们会对数据库进行多次调用。他们应该避免。查看n + 1查询问题。
出勤实际上只是讲座和学生之间的联系,那么为什么不使用这种关系来构建您的查询呢?有很多方法可以做到这一点。您可以尝试使用joins编写更清晰的单行内容,它只会为您提供所需的数据。在模型上通过关系添加has_many将基本上为您构建这个。由于看起来您已经有一个讲座对象可以从您的控制器和您的讲座展示页面获得,您可以在您的讲座模型中创建一个关系,该关系将返回参加该讲座的学生。它可能是这样的:
class Lecture < ActiveRecord::Base
has_many :attendances
has_many :attended_students, through: :attendances, class_name: "Student"
end
class Attendance < ActiveRecord::Base
belongs_to :student
belongs_to :lecture
end
在app / views / lectures / show.html.erb
中<ul>
<% @lecture.attended_students.each do |student| %>
<li><%=student.friendly_name%></li>
<% end %>
</ul>
如果您更正了我在评论中提到的缺少erb标记的问题,那么ajax也适用于您。