【问题标题】:Problem when checking if a data is null in a database in rails检查rails数据库中的数据是否为空时出现问题
【发布时间】:2024-04-28 18:30:03
【问题描述】:

我有问题。我在页面上有一个表单,它在文本输入中接收主题的代码,在进行相应检查时,其中一个给出了错误的结果。

在监控控制器中:

def inscribir
    @student = Student.find(params[:student_id])

    grupoDisponible = Student.buscarMateriaDisponible(params[:student_id],params[:codigo_materia])
    vioMateria = Student.vioCurso(params[:student_id], params[:codigo_materia])
    cumplePromedio = Student.calcPromedio(params[:student_id])
    creditos = Student.calc_credits(params[:student_id])

    @mensaje = "No se pudo asignar monitor a esa materia.\nRazon: "
    @todoBien = true
    if !grupoDisponible
        @todoBien = false
        @mensaje = @mensaje + "El grupo ya tiene monitor disponible."
        puts "El grupo ya tiene monitor disponible."
    end
    if !vioMateria
        @todoBien = false
        @mensaje = @mensaje + "El estudiante no ha visto la materia aun"
        puts "El estudiante no ha visto la materia aun"
    end
    if !cumplePromedio
        @todoBien = false
        @mensaje = @mensaje + "El estudiante no cumple el promedio requerido ser monitor"
        puts "El estudiante no cumple el promedio requerido ser monitor"
    end
    if creditos < 22
        @todoBien = false
        @mensaje = @mensaje + "El estudiante no cumple con los minimos creditos vistos."
        puts "El estudiante no cumple con los minimos creditos vistos."
    end
    if @todoBien
        @mensaje = Student.ingresarMonitoria(params[:student_id], params[:codigo_materia])
        puts @mensaje
    end
end

vioMateria 总是存储 false 值,即函数 vioCourse 总是返回 false。

函数 vioCourse(在模型中):

def self.vioCurso(id_student, cod_subject)

    puts id_student
    puts cod_subject
    logs = Student.find(id_student).logs
    encontrado = false
    logs.each do |log|
        codigo = Subject.find(log.subject_id).codigo
        if codigo == cod_subject
            encontrado = true
        end
    end
    return encontrado
end

该方法的逻辑很好,因为我已经尝试过rails控制台中的逻辑,用现有值替换变量,在这个它被执行,但是在网页中,并不总是给出false,而且,当我进入这个页面,总是执行整个代码,当boy to button总是给false时,输入参数没问题。

数据库不同表中的现有数据:

外壳:

Started POST "/students/1/monitorings/inscribir" for 127.0.0.1 at 2018-10-07 02:57:56 -0500
Processing by MonitoringsController#inscribir as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"+6Shqw+1nRkPnPt+ag/51tuJoVsH35Zip4fvsyR5FbCYjAdjECWrN56OOOb2iK5f+yyv8VhCIhYIZOp7IE7lMA==", "codigo_materia"=>"1256", "commit"=>"Buscar", "student_id"=>"1"}
  Student Load (0.0ms)  SELECT  "students".* FROM "students" WHERE "students"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
   (0.0ms)  SELECT COUNT(*) FROM "subjects" WHERE "subjects"."student_id" = ? AND "subjects"."codigo" = ?  [["student_id", 1], ["codigo", 1256]]
1
1256
  CACHE Student Load (0.0ms)  SELECT  "students".* FROM "students" WHERE "students"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
  Log Load (1.0ms)  SELECT "logs".* FROM "logs" WHERE "logs"."student_id" = ?  [["student_id", 1]]
  Subject Load (1.0ms)  SELECT  "subjects".* FROM "subjects" WHERE "subjects"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
  Subject Load (1.0ms)  SELECT  "subjects".* FROM "subjects" WHERE "subjects"."id" = ? LIMIT ?  [["id", 2], ["LIMIT", 1]]
  Subject Load (1.0ms)  SELECT  "subjects".* FROM "subjects" WHERE "subjects"."id" = ? LIMIT ?  [["id", 3], ["LIMIT", 1]]
  Subject Load (0.0ms)  SELECT  "subjects".* FROM "subjects" WHERE "subjects"."id" = ? LIMIT ?  [["id", 4], ["LIMIT", 1]]
  CACHE Student Load (0.0ms)  SELECT  "students".* FROM "students" WHERE "students"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
  CACHE Student Load (0.0ms)  SELECT  "students".* FROM "students" WHERE "students"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
  CACHE Log Load (0.0ms)  SELECT "logs".* FROM "logs" WHERE "logs"."student_id" = ?  [["student_id", 1]]
  CACHE Subject Load (0.0ms)  SELECT  "subjects".* FROM "subjects" WHERE "subjects"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
  CACHE Subject Load (0.0ms)  SELECT  "subjects".* FROM "subjects" WHERE "subjects"."id" = ? LIMIT ?  [["id", 2], ["LIMIT", 1]]
  CACHE Subject Load (0.0ms)  SELECT  "subjects".* FROM "subjects" WHERE "subjects"."id" = ? LIMIT ?  [["id", 3], ["LIMIT", 1]]
  CACHE Subject Load (0.0ms)  SELECT  "subjects".* FROM "subjects" WHERE "subjects"."id" = ? LIMIT ?  [["id", 4], ["LIMIT", 1]]
El estudiante no ha visto la materia aun
  Rendering monitorings/inscribir.html.erb within layouts/students
  Rendered students/_infoest.html.erb (1.0ms)
  Rendered monitorings/_inscripcion.html.erb (0.0ms)
  Rendered monitorings/inscribir.html.erb within layouts/students (40.9ms)
  Student Load (1.0ms)  SELECT  "students".* FROM "students" WHERE "students"."id" = ? ORDER BY "students"."id" ASC LIMIT ?  [["id", 1], ["LIMIT", 1]]
  Rendered layouts/_menu.html.erb (4.0ms)
  Rendered layouts/_footer.html.erb (0.0ms)
Completed 200 OK in 284ms (Views: 242.1ms | ActiveRecord: 5.0ms)

HTML 表单代码(在视图中):

<%= form_tag(inscribir_student_monitoring_post_path) do%>
    <%= text_field_tag 'codigo_materia', nil, placeholder: "Codigo de la materia", class: "EditBox", id: "EditboxCodigoMatInsMat"%>
    <hr id="LinSepComForm">

    <div id="wb_ButtonInsMatInsMat">
        <%= submit_tag "Buscar", id: "ButtonInsMatInsMat", class: "boton", style: "color: #FFFFFF"%> 
    </div>
<% end %>

谢谢

【问题讨论】:

    标签: ruby-on-rails database html sqlite ruby-on-rails-5


    【解决方案1】:

    不幸的是,我没有完全理解代码,并且有点懒得弄清楚它的含义。因此,在与其他开发人员合作时,使用英文变量会有很大帮助;)

    尽管如此,我认为可能有兴趣让您知道实现vioCurso 方法的更好方法,该方法不需要加载Student,他们所有的logssubjects,直接询问数据库检查记录是否存在。

    def self.vioCurso(student_id, subject_code)
      Subject.joins(:log).merge(Log.where(student_id: student_id)).where(codigo: subject_code).exists?
    end
    

    您甚至可以将其设为 ActiveRecord 范围:

    class Subject < ApplicationRecord
      scope :for_student_and_code, ->(student_id, subject_code) do
        joins(:log).merge(Log.where(student_id: student_id)).where(codigo: subject_code)
      end
    end
    

    然后做

    Subject.for_student_and_code(student_id, subject_code).exists?
    

    要详细了解joinsmerge 方法,请查看相应的API 文档:掌握这两个方法可以在各种情况下为您节省大量精力。

    我知道这可能无法回答您的问题,但发表评论并正确格式化它太长了......

    【讨论】: