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

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

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

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

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

>> 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 и ActionDispatch::Integration::RequestHelpers чтобы узнать, чем еще может быть полезен этот объект.

Попробуйте 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:

>> 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]


Этот способ спас меня от безмерного числа погружений в исходники. Пользуйтесь!
AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 3

    0
    Огромное спасибо, нереально полезные советы!
      +1
      Еще одна затея с helper-ом — использование переменных класса внури метода помощника.

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

      Можно ещё использовать pry вместо irb. Там этот функционал встроен в сам шелл.
        0
        Упс. Поправил, спасибо.

      Only users with full accounts can post comments. Log in, please.