mardi 21 juin 2016

update renders nonexistent record instead of skipping to next

In the "exposition" feature of my app users copy a term from the screen; if there are no spelling errors, the WordExposition model method next_exposition should link students to the next available word in the same lesson. It currently works as expected unless there is a gap in word_exposition id's--at which point, it links to the next ascending nonexistent record. This raises ActiveRecord::RecordNotFound in WordExpositionsController#show with the message Couldn't find WordExposition with [WHERE "word_expositions"."enrollment_id" = ? AND "word_expositions"."word_id" = ?]. How can I get this method to search for the next word_exposition in the lesson?

WordExposition model:

class WordExposition < ActiveRecord::Base
  belongs_to :enrollment
  belongs_to :word

  delegate :term, to: :word 

  attr_accessor :term_given_by_student
  validate :word_from_student_matches_word, on: :update

  def word_from_student_matches_word
    return true if word.term == term_given_by_student.split.join(' ')
  end

  #this breaks for non-adjacent records and for the last record
  def next_exposition
    WordExposition.where(["id > ? AND enrollment_id = ?", id, enrollment_id]).first
  end
end

WordExpositions controller:

class WordExpositionsController < ApplicationController
  def show
    @word = current_enrollment.word_expositions.find_by!(word_id: params[:id])
  end

  def update
    current_word_exposition
    @current_word_exposition.completed = true
    @current_word_exposition.term_given_by_student = params[:word_exposition][:term_given_by_student]
    if @current_word_exposition.save
      flash[:notice] = "Congratulations!"
      if next_word = @current_word_exposition.next_exposition
        redirect_to lesson_word_exposition_path(current_lesson, next_word)
      else
        redirect_to lesson_path(current_lesson)
      end 
    else
      flash[:alert] = "Enter the word exactly as shown!"
      redirect_to lesson_word_exposition_path(current_lesson, current_word_exposition)
    end
  end

  private
  helper_method :current_lesson
  def current_lesson
    @current_lesson ||= Lesson.find(params[:lesson_id])
  end

  helper_method :current_enrollment
  def current_enrollment
    @current_enrollment ||= Enrollment.find_by!(lesson_id: params[:lesson_id], user_id: current_user.id)
  end

  def word_exposition_params
    params.require(:word_exposition).permit(:completed)
  end

  helper_method :current_word_exposition
  def current_word_exposition
    @current_word_exposition ||= current_enrollment.word_expositions.find_by!(word_id: params[:id])
  end
end

form in WordExpositions show:

<%= simple_form_for @word, url: lesson_word_exposition_path(current_lesson, @word), method: :patch do |f| %>
  <%= f.input :term_given_by_student, label: "Enter the term exactly as above:" %><br>
  <%= f.button :submit, class: 'btn btn-primary' %>
<% end %>

Aucun commentaire:

Enregistrer un commentaire