Skip to content

Instantly share code, notes, and snippets.

@elvisgiv
Last active August 29, 2015 14:15
Show Gist options
  • Save elvisgiv/34af9f6f6171e52b4740 to your computer and use it in GitHub Desktop.
Save elvisgiv/34af9f6f6171e52b4740 to your computer and use it in GitHub Desktop.

#Этапы, на которых возможны неполадки.

  • Человек вводит адрес строки URL в свой браузер;
  • Браузер передает на сервер ЗАПРОС и COOKIES. У всех сайтов свои cookies, URL и параметры (последние передаются массивом значений, например http://www.amazon.com/Coupons/b/ref=sv_gb_2?ie=UTF8&node=2231352011, т.е. protocol :// domain / path ? params, где params - это ключ-значение (ie=UTF8 и node=2231352011)) справка см. http://searchengines.guru/showthread.php?t=630301;
  • Далее в дело вступают РЕЛЬСЫ и первым делом смотрят в РУТЫ (..\config\routes.rb). Цель роутера Rails - Роутер Rails распознает URL и соединяет их с экшном контроллера. Он также создает пути и URL, избегая необходимость писать тяжелый код в ваших вьюхах, и в рутах ищут соотретствия определенному экшену/методу определенного контроллера (..\app\controllers\names_controller.rb);
  • Соединение URL с кодом

Когда ваше приложение на Rails получает входящий запрос для: GET /patients/17

оно опрашивает роутер на предмет соответствия экшну контроллера. Если первый соответствующий маршрут это: get '/patients/:id', to: 'patients#show'

то запрос будет направлен в контроллер patients в экшн show с { id: '17' } в params

  • Система запускает экшен в этом контроллере...НО! До этого МОЖЕТ отработать код, который находится в callback'ах before_action или файле application_controller.rb (..\app\controllers\application_controller.rb), который является главным среди всех контроллеров;
  • Запускается обработка текста в файле action_name.html.haml (по умолчанию экшен рендерит вьюху, которрая находится в папке controller_names и имеет название экшена с расширением .html.haml, например \app\views\devices\index.html.haml означает, что для контроллера devices_controller.rb, экшена def index, была создана вьюха/шаблон index.html.haml). НО!!! экшен также может РЕНДЕРИТЬ свои данные и на ДРУГУЮ вьюху!
  • Вьюха может работать только с переменными того экшена, который рендерит на нее и перед ними ОБЯЗАТЕЛЬНО должен стоять знак @, например @devices.

##Примеры: ###Найти запись в DB, которая выдает ошибку Есть бесконечное число записей, в которых только одна выдает ошибку. Есть код моделей:

class Device < ActiveRecord::Base
  belongs_to :device_model
  has_many   :orders
  
  validates :title,                       presence: true
  validates :serial,                      :presence => true
  validates :serials_additional,          :presence => false
  validates :bought,                      presence: false
  validates :device_model_id,             presence: true
end

class DeviceModel < ActiveRecord::Base
 	belongs_to :device_category
 	belongs_to :device_brand
 	has_many   :devices
end

class DeviceBrand < ActiveRecord::Base
 	has_many :device_models
end

class DeviceCategory < ActiveRecord::Base
  has_many :device_models
end

Есть код контроллера:

class DevicesController < ApplicationController
  before_action :set_device, only: [:show, :edit, :update, :destroy]
  def index
    @devices = Device.includes(:device_model => [:device_brand, :device_category]).all
  end
  ...
end

Есть код вьюхи:

%h1 Listing devices

%table.table
  %thead
    %tr
      %th Title
      %th Serial
      %th Serials additional
      %th Bought
      %th Device model
      %th Device brand
      %th Device category
      %th Date of create
      %th Date of update
      %th Edit/Destroy
     
%tbody
  - @devices.each do |t|
    %tr
      %td= t.title 
      %td= t.serial
      %td= t.serials_additional
      %td= t.bought
      %td= t.device_model.title
      %td= t.device_model.device_brand.title
      %td= t.device_model.device_category.title
      %td= t.created_at
      %td= t.updated_at
      %td
        = link_to 'Edit', edit_device_path(t)
        \/
        = link_to 'Destroy', t, :method => :delete, :data => { :confirm => 'Are you sure?' }

Есть ошибка:

 Started GET "/ac/devices" for 127.0.0.1 at 2015-02-21 20:44:34 +0200
 Processing by DevicesController#index as HTML
   Device Load (148.0ms)  SELECT `devices`.* FROM `devices`
   DeviceModel Load (154.0ms)  SELECT `device_models`.* FROM `device_models`  WHE
 RE `device_models`.`id` IN (1, 2, 7, 4, 5)
   DeviceBrand Load (23.0ms)  SELECT `device_brands`.* FROM `device_brands`  WHER
 E `device_brands`.`id` IN (4, 1, 3, 5)
   DeviceCategory Load (3.0ms)  SELECT `device_categories`.* FROM `device_categor
 ies`  WHERE `device_categories`.`id` IN (2, 5, 3, 1)
 Rendered devices/index.html.haml within layouts/application (1783.1ms)
 Completed 500 Internal Server Error in 3201ms
 
 ActionView::Template::Error (undefined method `title' for nil:NilClass):
     21:         %td= t.serial
     22:         %td= t.serials_additional
     23:         %td= t.bought
     24:         %td= t.device_model.title
     25:         %td= t.device_model.device_brand.title
     26:         %td= t.device_model.device_category.title
     27:         %td= t.created_at
   app/views/devices/index.html.haml:24:in `block in _app_views_devices_index_htm
 l_haml___452187739_40940412'
   app/views/devices/index.html.haml:18:in `_app_views_devices_index_html_haml___
 452187739_40940412'

Которая сообщает нам о том, что какая-то из записей "битая".

Чтобы выяснить которая из записей "битая", пишем logger.debug перед t.title:

...
%td= logger.debug t.title 
...

И обновляем экран.

Идем в логи и видим ту же ошибку, но уже с именем строки, на которой прервался цикл (HTC Eclipse-3):

Started GET "/ac/devices" for 127.0.0.1 at 2015-02-21 20:44:34 +0200
Processing by DevicesController#index as HTML
  Device Load (148.0ms)  SELECT `devices`.* FROM `devices`
  DeviceModel Load (154.0ms)  SELECT `device_models`.* FROM `device_models`  WHE
RE `device_models`.`id` IN (1, 2, 7, 4, 5)
  DeviceBrand Load (23.0ms)  SELECT `device_brands`.* FROM `device_brands`  WHER
E `device_brands`.`id` IN (4, 1, 3, 5)
  DeviceCategory Load (3.0ms)  SELECT `device_categories`.* FROM `device_categor
ies`  WHERE `device_categories`.`id` IN (2, 5, 3, 1)
HTC Eclipse
HTC Eclipse-2
HTC Eclipse-3
  Rendered devices/index.html.haml within layouts/application (1783.1ms)
Completed 500 Internal Server Error in 3201ms

ActionView::Template::Error (undefined method `title' for nil:NilClass):
    21:         %td= t.serial
    22:         %td= t.serials_additional
    23:         %td= t.bought
    24:         %td= t.device_model.title
    25:         %td= t.device_model.device_brand.title
    26:         %td= t.device_model.device_category.title
    27:         %td= t.created_at
  app/views/devices/index.html.haml:24:in `block in _app_views_devices_index_htm
l_haml___452187739_40940412'
  app/views/devices/index.html.haml:18:in `_app_views_devices_index_html_haml___
452187739_40940412'

Дальше лезем в базу, находим запись и исправляем ее.

###Полезная ссылка

http://guides.rubyonrails.org/debugging_rails_applications.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment