- PVSM.RU - https://www.pvsm.ru -

Три полезных совета по Rails консоли

Топик является вольным переводом статьи на 37signals [1].

Вчера я копался в документации к Rails API и заметил несколько полезных функций rails консоли, которых не видел ранее [2]. До этого было [3] множество [4] публикаций [5] об irb и Rails, но я надеюсь, что из этой вы почерпнете для себя что-то новое. Приведенные примеры сделаны с использованием Basecamp Next on Rails версии 3.2.3.

Погрузитесь в свое приложение

Использование app метода в консоли создает экземпляр сессии, в результате чего в ней можно пользоваться возможностями обычного интеграционного теста [6].

>> app.class
=> ActionDispatch::Integration::Session

Формировать маршруты всегда было напряжно. Какой там модуль надо было подключить? Вы не забыли указать default_url_options? Прекращайте гуглить и просто используйте app:

>> app.project_path(Project.first)
=> "/projects/130349783-with-attachments"

Он также может создавать запросы внутри приложения:

>> app.get "/735644780/projects/605816632-bcx.atom"
=> 200

>> app.response.body
=> "<?xml version="1.0" encoding="UTF-8"?>n<feed xml:lang="en-US" ...

Гляньте ActionDispatch::Integration::Session [7] и ActionDispatch::Integration::RequestHelpers [8] чтобы узнать, чем еще может быть полезен этот объект.

Попробуйте helper

Связывать консольную сессию с Rails помощниками тоже болезненно, но helper может это исправить! Eще его можно использовать, чтобы поиграться с созданием HTML тегов или любым другим Rails помощником, о существовании которого знает ActionView.

>> helper.truncate("Testing", length: 4)
=> "T..."

>> helper.link_to "Home", app.root_path
=> "Home"

Еще одна затея с helper-ом — использование переменных класса внури метода помощника. Да, я знаю, что это Плохая Идея™ для помощников в целом, но без таковой не обходилось еще ни одно моё Rails приложение. Вот небольшой пример метода:

def title_tag(title = nil)
if @project.present? && title.nil?
content_tag :title, @project.name
elsif @project.present?
content_tag :title, "#{@project.name}: #{title}"
else
content_tag :title, title
end
end

Можно прибегнуть к помощи старого приятеля Object#instance_variable_set, чтобы нарушить основной принцип ООП, позвольте попробовать helper в консоли:

>> helper.title_tag "Testing!"
=> "Testing!"

>> helper.instance_variable_set :@project, Project.first
=> #<Project id: 130349783, ...

>> helper.title_tag
=> "With attachments!"

>> helper.title_tag "Posts"
=> "With attachments!: Posts"

Работать с helper-ом, использующим params, тоже не слишком просто. Однако, при помощи крошечного хака мы можем заставить ActionView слушаться нас. Это же консоль, в конце концов! Положим, у нас есть метод помощник:

def javascript_debugging_options
if params[:javascript_debugging] == "enabled"
{ debug: true, digest: false }
else
{}
end
end

Обычно ActionView требуется весь ActionDispatch::Request из контроллера, чтобы определить, какие параметры пришли от пользователя. Можно обмануть его, используя небольшой OpenStruct [9]:

>> helper.controller = OpenStruct.new(params: {})
=> #<OpenStruct params={}>

>> helper.javascript_debugging_options
=> {}

>> helper.controller = OpenStruct.new(params: {javascript_debugging: "enabled"})
=> #<OpenStruct params={:javascript_debugging=>"enabled"}>

>> helper.javascript_debugging_options
=> {:debug=>true, :digest=>false}

Откуда появился этот метод?

Отследить точное расположение нужного метода не всегда просто. К счастью, Ruby может указать нужное направление при помощи Method#source_location:

>> Project.instance_method(:trash).source_location
=> ["/Users/qrush/37s/apps/bcx/app/models/project.rb", 90]

Уоу! Вы получите массив, содержащий полный путь к методу, вместе с номером строки этого метода в файле.

Я пользовался этим и тогда, когда искал код, зарытый глубоко в гемах. Давайте проверим на app:

>> app.method(:get).source_location
=> ["/Users/qrush/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/bundler/gems/rails-7d95b814583b/actionpack/lib/action_dispatch/testing/integration.rb", 32]

Этот способ спас меня от безмерного числа погружений в исходники. Пользуйтесь!

Автор: tmnTurtle


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/perevod/8218

Ссылки в тексте:

[1] 37signals: http://37signals.com/svn/posts/3176-three-quick-rails-console-tips

[2] которых не видел ранее: http://api.rubyonrails.org/classes/Rails/ConsoleMethods.html

[3] было: http://slash7.com/2006/12/21/secrets-of-the-rails-console-ninjas/

[4] множество: http://railscasts.com/episodes/48-console-tricks

[5] публикаций: http://rors.org/2009/12/20/10-rails-console-tricks.html

[6] интеграционного теста: http://guides.rubyonrails.org/testing.html#integration-testing

[7] ActionDispatch::Integration::Session: http://api.rubyonrails.org/classes/ActionDispatch/Integration/Session.html

[8] ActionDispatch::Integration::RequestHelpers: http://api.rubyonrails.org/classes/ActionDispatch/Integration/RequestHelpers.html

[9] OpenStruct: http://ruby-doc.org/stdlib-1.9.3/libdoc/ostruct/rdoc/OpenStruct.html