ActiveRecord :: StatementInvalid(PG :: SyntaxError:ERROR:语法错误位于或接近“。”

时间:2015-07-27 12:17:18

标签: ruby-on-rails postgresql activerecord

我不确定为什么我的查询在localhost上运行但在服务器上失败。 当我尝试创建一个路由到QuizzesController #new

的测验时会发生这种情况
    public  string  getUrl(string code )   
    {
        switch (code)

        {

          case  "1": 
              return "#";
          case "2":
              return "#";
          case "3": 
              return "#";
          case "4":
              return "#";
          case "5": 
              return "#";
          case "6": 
              return "#";
          case "7": 
              return "#";
          default:
              return "Unknown case occured!";

        }

    }

这是查询:

# GET /quizzes/new
  def new
    @quiz = current_user.quizzes.new
  end

我得到了一个错误。

SELECT COUNT(*) FROM "questions" INNER JOIN "question_categories" ON "question_categories"."question_id" = "questions"."id" WHERE "questions"."deleted_at" IS NULL AND (`question_categories`.`category_id` IN (87,1))

(1.0ms)  ROLLBACK
Completed 500 Internal Server Error in 58ms (ActiveRecord: 13.4ms)

quiz.rb 在创建之前我会运行build_parts,它应该随机抓取问题并将它们放入测验中。     课堂测验<的ActiveRecord :: Base的       belongs_to:用户       belongs_to:subject       has_many:quiz_categories       has_many:类别,通过:: quiz_categories       has_many:quiz_parts

ActiveRecord::StatementInvalid (PG::SyntaxError: ERROR:  syntax error at or near "." LINE 1: ...s"."deleted_at" IS NULL AND (`question_categories`.`category...

quizzes_controller.rb

  accepts_nested_attributes_for :categories
  accepts_nested_attributes_for :quiz_parts

  validates :user, :subject, :number_of_questions, presence: true
  validates :number_of_questions, numericality: { only_integer: true, greater_than_or_equal_to: 1 }

  before_create :build_parts
  before_save :set_completed_at, if: -> { completeness == 100.00 }

  def completeness
    answerable_quiz_parts = 0
    quiz_parts.each do |q_part|
      answerable_quiz_parts += 1 if q_part.answerable.answers.present?
    end
    quiz_parts.joins(:choice).count.to_f * 100 / answerable_quiz_parts
  end

  def score
    quiz_parts.joins(:choice).where('choices.correct = ?', true).count { |qp| qp.choice.correct? }
  end

  private

  # select random questions
  def build_parts
    category_ids = self.categories.map(&:id)
    question_pool = Question.joins(:question_categories).where('`question_categories`.`category_id` IN (?)', category_ids)

    #self.number_of_questions = [number_of_questions, question_pool.size].min

    puts question_pool.size

    if number_of_questions > question_pool.size
      errors.add(:number_of_questions, 'is too high. Please select a lower question count or increase category selections')
      return false
    end

    number_of_questions.times do |i|
      question_pool.inspect
      self.quiz_parts << question_pool[i].quiz_parts.new
      question_pool[i].question_parts.each do |question_part|
        self.quiz_parts << question_part.quiz_parts.new
      end
    end
  end

  def set_completed_at
    self.completed_at = Time.zone.now
  end

end

schema.rb:

class QuizzesController < ApplicationController
  before_action :authenticate_user!
  before_action :set_quiz, only: [:show, :edit, :update, :destroy]

  # GET /quizzes
  # GET /quizzes.json
  def index
    @quizzes = current_user.quizzes.order(created_at: :desc)
  end

  # GET /quizzes/1
  # GET /quizzes/1.json
  def show
  end

  # GET /quizzes/new
  def new
    @quiz = current_user.quizzes.new
  end

  # GET /quizzes/1/edit
  def edit

  end

  # POST /quizzes
  # POST /quizzes.json
  def create
    @quiz = current_user.quizzes.new(quiz_create_params)
    respond_to do |format|
      if @quiz.save
        format.html { redirect_to edit_quiz_path(@quiz), notice: 'Quiz was successfully created.' }
        format.json { render :show, status: :created, location: @quiz }
      else
        format.html { render :new }
        format.json { render json: @quiz.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /quizzes/1
  # PATCH/PUT /quizzes/1.json
  def update
    respond_to do |format|
      if @quiz.update(quiz_update_params)
        format.html { redirect_to @quiz, notice: 'Quiz was successfully updated.' }
        format.json { render :show, status: :ok, location: @quiz }
      else
        format.html { render :edit }
        format.json { render json: @quiz.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /quizzes/1
  # DELETE /quizzes/1.json
  def destroy
    @quiz.destroy
    respond_to do |format|
      format.html { redirect_to quizzes_url, notice: 'Quiz was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
  # Use callbacks to share common setup or constraints between actions.
  def set_quiz
    @quiz = current_user.quizzes.find(params[:id])
  end

  # For quiz setup
  def quiz_create_params
    params.require(:quiz).permit(:subject_id, :number_of_questions, category_ids: [])
  end

  # For quiz answering
  def quiz_update_params
    params.require(:quiz).permit(quiz_parts_attributes: [:id, choice_attributes: [:id, :content, :answer_id, :_destroy]])
  end
end

1 个答案:

答案 0 :(得分:5)

我相信你使用的是错误的引号:

SELECT COUNT(*) ....... (`question_categories`.`category_id` IN (87,1))
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

使用" "代替``

更新

是的,我一直在您的测验模型中使用错误的引号:

def build_parts
  category_ids = self.categories.map(&:id)
  question_pool = Question.joins(:question_categories).where('`question_categories`.`category_id` IN (?)', category_ids)
                                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

将其修复为:

 def build_parts
   category_ids = self.categories.map(&:id)
   question_pool = Question.joins(:question_categories).where('"question_categories"."category_id" IN (?)', category_ids)
                                                               ^^^^^^^^^^^^^^^^^^^^^