mardi 21 avril 2015

Refactoring custom controller actions in rails

I have been working to create a way to update my index view via checkboxes. It is worth mentioning that i am using Mongoid. As i only wanted to use these checkboxes and as a way to clear up the index view at this stage i have done it via a complete action in the existing controller. I followed the railscast (#52) on the matter too and it was very helpful! I am now at the point where the logic is working but needs some serious refactoring. I am a little confused though as to how is best to write controller specs on custom actions. I shall put below what i tried but it also through me some errors. I was also wondering if it would be better that i used default scope on the model and tested in the model until spec but implementing this is something i am not quite sure how to do. Could anyone offer any suggestions on this matter.

Index:

%h1 Diagnostics
= form_tag complete_admin_diagnostics_path, :method => :put do
  %table
    %tr
      %th
      %th User
      %th Message
      %th Device
      %th RELS-Mobile Version
      %th Submitted
      %th Archive
    - @diagnostics.each do |diagnostic| 
      %tr
        %td
          %strong= link_to 'show', admin_diagnostic_path(diagnostic)
        %td
          - if diagnostic.user
            = link_to diagnostic.user.email, [:admin, diagnostic.user]
          - else
            unknown
        %td
          = diagnostic.data["message"]
        %td
          %pre= JSON.pretty_generate(diagnostic.data["device"])
        %td
          = diagnostic.data["appVersion"]
        %td
          = diagnostic.updated_at
        %td
          = check_box_tag "diagnostic_ids[]", diagnostic.id
          = diagnostic.data

    = submit_tag "Mark as complete"
= paginate @diagnostics

Controller:

class Admin::DiagnosticsController < Admin::BaseController
  before_filter :diagnostic, :except => [:index, :complete]

  def index
     @diagnostics = DiagnosticInfo.where(:completed_at => nil).order_by(:created_at.desc).page(params[:page]).per(50)
  end

  def show
    respond_to do |format|
      format.html
      format.json { render json: @diagnostic }
    end
  end

  def update
    if @diagnostic.update_attributes(params[:diagnostic_info])
      redirect_to admin_diagnostic_path, notice: 'Successfully updated.'
    else
      render action: "edit"
    end
  end

  def edit
  end

  def destroy
    diagnostic.destroy
    redirect_to admin_diagnostics_path
  end

  def complete
    DiagnosticInfo.where(:id.in => params[:diagnostic_ids]).each do |diagnostic_info|
      diagnostic_info.touch(:completed_at)
    end
    redirect_to admin_diagnostics_path
  end


private

  def diagnostic
    @diagnostic = DiagnosticInfo.find(params[:id])
  end
end

New controller spec test:

      # describe "PUT update" do 
  #   it "it archives a diagnostic info report" do 
  #     diagnostic = FG.create(:diagnostic_info)
  #     expect {
  #      put :index, :id => diagnostic.id
  #      }.to change(DiagnosticInfo, :count).by(0)
  #     response.should redirect_to(admin_diagnostics_url)
  #   end
  # end

Relevant Feature test spec

  it "can archive a diagnostic report" do 
    diagnostic_info = FG.create(:diagnostic_info)
    visit admin_diagnostics_path
    page.should have_content("test message")
    # save_and_open_page-launchy
    check('diagnostic_ids[]')
    # click_button  "Mark as complete"
    expect { click_button "Mark as complete" }.to change(DiagnosticInfo, :count).by(1)
  end
end

Relevant section from Routes.rb

resources :diagnostics do 
      put 'complete', on: :collection
    end

Controller spec

1) Admin::DiagnosticsController PUT update it archives a diagnostic info report
     Failure/Error: response.should redirect_to(admin_diagnostics_url)
       Expected response to be a <:redirect>, but was <200>
     # ./spec/controllers/admin/diagnostics_controller_spec.rb:54:in `block (3 levels) in <top (required)>'

Aucun commentaire:

Enregistrer un commentaire