Як я можу викликати контролер / переглядати допоміжні методи з консолі в Ruby on Rails?


442

Коли я завантажуюсь script/console, іноді мені хочеться грати з виходом контролера або методом помічника перегляду.

Чи є способи:

  • імітувати запит?
  • методи виклику з екземпляра контролера за вказаним запитом?
  • тест-помічники, або через вказаний екземпляр контролера, або іншим способом?

Відповіді:


479

Щоб викликати помічників, використовуйте helperоб'єкт:

$ ./script/console
>> helper.number_to_currency('123.45')
=> "R$ 123,45"

Якщо ви хочете використовувати помічник , який не включений за замовчуванням (наприклад, тому що ви видалили helper :allз ApplicationController), просто включити помічник.

>> include BogusHelper
>> helper.bogus
=> "bogus output"

Що стосується роботи з контролерами , я цитую відповідь Ніка :

> app.get '/posts/1'
> response = app.response
# you now have a rails response object much like the integration tests

> response.body            # get you the HTML
> response.cookies         # hash of the cookies

# etc, etc

4
Я зауважую, що я не можу виконати більше одного app.get(виникає помилка потоку). Чи є спосіб я змити систему та виконати більше отриманих?
JellicleCat

2
Примітка в Rails 3.2 це не працює. Мені потрібно було зателефонувати url_forз консолі. Для цього я зробивapp.url_for(...)
Рафаель

1
Для NoMethodError: undefined method `protect_against_forgery?' for nil:NilClassвизначення функції, викликаної protect_against_forgery?в консолі, яка повертаєтьсяfalse
Sida Zhou

як встановити користувача, який увійшов в даний момент?

1
@RudolfOlah Здається, що якщо ви користуєтесь пристроєм (або керуючим), ви можете це зробити ActionDispatch::Integration::Session.include(Warden::Test::Helpers); Warden.test_mode! ; app.login_as(User.find(1), scope: :user).
eloyesp

148

Найпростіший спосіб викликати дії контролера зі скрипту / консолі та переглядати / маніпулювати об'єктом відповіді:

> app.get '/posts/1'
> response = app.response
# You now have a Ruby on Rails response object much like the integration tests

> response.body            # Get you the HTML
> response.cookies         # Hash of the cookies

# etc., etc.

Об'єкт програми - це примірник ActionController :: Integration :: Session

Це працює для мене за допомогою Ruby on Rails 2.1 і 2.3, і я не пробував попередні версії.


2
Посилання на офіційну документацію щодо об’єкта програми було б добре.
RajaRaviVarma

Це екземпляр класу ActionController :: Integration :: Session. Я оновив відповідь, щоб включити її.
Нік

Чудова ідея. Я не думав про це.
Marnen Laibow-Koser

5
Як я можу аутентифікувати консоль, щоб я міг перевірити контролери, які потребують аутентифікації?
Легкий фузз

7
Ви повинні мати можливість публікувати на своїй сторінці входу щось на зразок: app.post '/ session / new', {: username => "foo",: password => "pass"}. А потім продовжуйте використовувати ту саму змінну "app", щоб отримати сторінки після цього.
Нік

108

Якщо вам потрібно протестувати з консолі (протестовано на Ruby on Rails 3.1 і 4.1):

Дії контролера виклику:

app.get '/'
   app.response
   app.response.headers  # => { "Content-Type"=>"text/html", ... }
   app.response.body     # => "<!DOCTYPE html>\n<html>\n\n<head>\n..."

Методи ApplicationController:

foo = ActionController::Base::ApplicationController.new
foo.public_methods(true||false).sort
foo.some_method

Помічники маршруту:

app.myresource_path     # => "/myresource"
app.myresource_url      # => "http://www.example.com/myresource"

Переглянути помічників:

foo = ActionView::Base.new

foo.javascript_include_tag 'myscript' #=> "<script src=\"/javascripts/myscript.js\"></script>"

helper.link_to "foo", "bar" #=> "<a href=\"bar\">foo</a>"

ActionController::Base.helpers.image_tag('logo.png')  #=> "<img alt=\"Logo\" src=\"/images/logo.png\" />"

Візуалізація:

views = Rails::Application::Configuration.new(Rails.root).paths["app/views"]
views_helper = ActionView::Base.new views
views_helper.render 'myview/mytemplate'
views_helper.render file: 'myview/_mypartial', locals: {my_var: "display:block;"}
views_helper.assets_prefix  #=> '/assets'

Методи ActiveSupport:

require 'active_support/all'
1.week.ago
=> 2013-08-31 10:07:26 -0300
a = {'a'=>123}
a.symbolize_keys
=> {:a=>123}

Модулі Lib:

> require 'my_utils'
 => true
> include MyUtils
 => Object
> MyUtils.say "hi"
evaluate: hi
 => true

1
Це допомагає, коли ви пишете незалежні сценарії рубіну, які запускатимуться за допомогою рейки бігуна і їм потрібно викликати методи в контролері додатків. Спасибі
CodeExpress

@CodeExpress Це ніколи не повинно статися. Замість цього помістіть методи в об’єкт обслуговування та зателефонуйте в службу як через ApplicationController, так і зі свого сценарію.
Marnen Laibow-Koser

77

Ось один із способів зробити це за допомогою консолі:

>> foo = ActionView::Base.new
=> #<ActionView::Base:0x2aaab0ac2af8 @assigns_added=nil, @assigns={}, @helpers=#<ActionView::Base::ProxyModule:0x2aaab0ac2a58>, @controller=nil, @view_paths=[]>

>> foo.extend YourHelperModule
=> #<ActionView::Base:0x2aaab0ac2af8 @assigns_added=nil, @assigns={}, @helpers=#<ActionView::Base::ProxyModule:0x2aaab0ac2a58>, @controller=nil, @view_paths=[]>

>> foo.your_helper_method(args)
=> "<html>created by your helper</html>"

Створення нового екземпляра ActionView::Baseдає вам доступ до звичайних методів перегляду, які, можливо, використовує ваш помічник. Потім розширення YourHelperModuleзмішує його методи у ваш об'єкт, дозволяючи переглядати їх повернені значення.


15

Якщо метод - POSTметод, то:

app.post 'controller/action?parameter1=value1&parameter2=value2'

(Тут параметри будуть відповідати вашим застосункам.)

Ще, якщо це GETметод тоді:

app.get 'controller/action'

1
І щоб знайти потрібні вам шляхи, app.methods.grep(/_path/):)
Доріан

І це не завжди controler/action, залежить від ваших маршрутів, наприклад, можна було б /users/allі зробити карту Api::UsersController#index:)
Доріан,

@Dorian Or rake routes. :)
Marnen Laibow-Koser

14

Інший спосіб зробити це - використовувати налагоджувач Ruby on Rails. Існує посібник Ruby on Rails про налагодження на веб- сторінці http://guides.rubyonrails.org/debugging_rails_applications.html

В основному, запустіть сервер за допомогою параметра -u:

./script/server -u

А потім вставити в свій скрипт точку розриву, де ви хочете мати доступ до контролерів, помічників тощо.

class EventsController < ApplicationController
  def index
    debugger
  end
end

І коли ви зробите запит і натиснете цю частину коду, консоль сервера поверне запит, де ви зможете робити запити, переглядати об'єкти тощо з командного рядка. Закінчивши, просто введіть 'cont', щоб продовжити виконання. Існують також варіанти розширеної налагодження, але це має принаймні почати роботу.


3
> => Примітка: параметр налагодження ігнорується з Ruby 2.0, і він буде видалений у майбутніх версіях.
яскраво-зірка

13

Ось як зробити автентифікований запит POST, використовуючи НПЗ як приклад:

# Start Rails console
rails console
# Get the login form
app.get '/community_members/sign_in'
# View the session
app.session.to_hash
# Copy the CSRF token "_csrf_token" and place it in the login request.
# Log in from the console to create a session
app.post '/community_members/login', {"authenticity_token"=>"gT7G17RNFaWUDLC6PJGapwHk/OEyYfI1V8yrlg0lHpM=",  "refinery_user[login]"=>'chloe', 'refinery_user[password]'=>'test'}
# View the session to verify CSRF token is the same
app.session.to_hash
# Copy the CSRF token "_csrf_token" and place it in the request. It's best to edit this in Notepad++
app.post '/refinery/blog/posts', {"authenticity_token"=>"gT7G17RNFaWUDLC6PJGapwHk/OEyYfI1V8yrlg0lHpM=", "switch_locale"=>"en", "post"=>{"title"=>"Test", "homepage"=>"0", "featured"=>"0", "magazine"=>"0", "refinery_category_ids"=>["1282"], "body"=>"Tests do a body good.", "custom_teaser"=>"", "draft"=>"0", "tag_list"=>"", "published_at(1i)"=>"2014", "published_at(2i)"=>"5", "published_at(3i)"=>"27", "published_at(4i)"=>"21", "published_at(5i)"=>"20", "custom_url"=>"", "source_url_title"=>"", "source_url"=>"", "user_id"=>"56", "browser_title"=>"", "meta_description"=>""}, "continue_editing"=>"false", "locale"=>:en}

Ви також можете виявити ці корисні, якщо ви отримаєте помилку:

app.cookies.to_hash
app.flash.to_hash
app.response # long, raw, HTML

2
NameError: undefined local variable or method app for main:Object
Каміль Лелонек

вам також потрібно відключити підробку_захистуApplicationController.allow_forgery_protection = false
Вільям

Нічого собі, мабуть, простіше. Те, що я написав, є захистом від підробки. Вам не потрібно його відключати, але я впевнений, що це зручніше!
Хлоя

12

Ви можете отримати доступ до своїх методів на консолі Ruby on Rails таким чином:

controller.method_name
helper.method_name


7

Раніші відповіді - це виклики помічників, але наступне допоможе для виклику методів контролера. Я використав це на Ruby on Rails 2.3.2.

Спочатку додайте наступний код у свій .irbrc файл (який може бути у вашому домашньому каталозі)

class Object
   def request(options = {})
     url=app.url_for(options)
     app.get(url)
     puts app.html_document.root.to_s
  end
end

Потім у консолі Ruby on Rails ви можете ввести щось на зразок ...

request(:controller => :show, :action => :show_frontpage)

... і HTML буде перекинуто на консоль.


3

Всередині будь-якої дії чи перегляду контролера можна викликати консоль, зателефонувавши до консольного методу.

Наприклад, у контролері:

class PostsController < ApplicationController
  def new
    console
    @post = Post.new
  end
end

Або в перегляді:

<% console %>

<h2>New Post</h2>

Це зробить консоль всередині вашого перегляду. Вам не потрібно дбати про місце виклику консолі; він не відображатиметься на місці його виклику, але поруч із вмістом HTML.

Дивіться: http://guides.rubyonrails.org/debugging_rails_applications.html


3

Для контролерів ви можете інстанціювати об’єкт контролера в консолі Ruby on Rails.

Наприклад,

class CustomPagesController < ApplicationController

  def index
    @customs = CustomPage.all
  end

  def get_number
    puts "Got the Number"
  end

  protected

  def get_private_number
    puts 'Got private Number'
  end

end

custom = CustomPagesController.new
2.1.5 :011 > custom = CustomPagesController.new
 => #<CustomPagesController:0xb594f77c @_action_has_layout=true, @_routes=nil, @_headers={"Content-Type"=>"text/html"}, @_status=200, @_request=nil, @_response=nil>
2.1.5 :014 > custom.get_number
Got the Number
 => nil

# For calling private or protected methods,
2.1.5 :048 > custom.send(:get_private_number)
Got private Number
 => nil

Це працює! Але як я можу оновити змінні дії. Наприклад: def show response = @user.contributions end Як я можу змінити @userзмінну?
Fábio Araújo

2

Один з можливих підходів для тестування методу Helper на консолі Ruby on Rails:

Struct.new(:t).extend(YourHelper).your_method(*arg)

А для перезавантаження робіть:

reload!; Struct.new(:t).extend(YourHelper).your_method(*arg)

1

Якщо ви додали власного помічника і хочете, щоб його методи були доступні в консолі, зробіть:

  1. У консолі виконати include YourHelperName
  2. Ваші допоміжні методи тепер доступні в консолі, і використовуйте їх для виклику method_name(args)в консолі.

Приклад: скажіть, що у вас є MyHelper (із методом my_method) у програмі "app / helpers / my_helper.rb", а потім у консолі виконайте:

  1. include MyHelper
  2. my_helper.my_method
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.