¿Cómo puedo llamar a los métodos de ayuda de controlador / vista desde la consola en Ruby on Rails?

442

Cuando cargo script/console, a veces quiero jugar con la salida de un controlador o un método de ayuda de vista.

¿Hay formas de:

  • simular una solicitud?
  • llamar a métodos de una instancia de controlador en dicha solicitud?
  • prueba métodos auxiliares, ya sea a través de dicha instancia de controlador o de otra manera?
kch
fuente

Respuestas:

479

Para llamar a los ayudantes, use el helperobjeto:

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

Si desea utilizar un ayudante que no está incluido por defecto (por ejemplo, cuando se quitan helper :allde ApplicationController), basta con incluir el ayudante.

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

En cuanto a tratar con controladores , cito la respuesta de Nick :

> 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
kch
fuente
44
Observo que no puedo ejecutar más de uno app.get(se produce un error de subproceso). ¿Hay alguna manera de poder vaciar el sistema y ejecutar más get?
JellicleCat
2
Nota en Rails 3.2 esto no funciona. Necesitaba llamar url_fordesde la consola. Para hacer esto lo hiceapp.url_for(...)
Raphael
1
Para NoMethodError: undefined method `protect_against_forgery?' for nil:NilClassdefinir una función llamada protect_against_forgery?dentro de la consola que regresafalse
Sida Zhou
¿Cómo configuro el usuario actualmente conectado?
1
@RudolfOlah Parece que si está utilizando un dispositivo (o un guardián) puede hacerlo ActionDispatch::Integration::Session.include(Warden::Test::Helpers); Warden.test_mode! ; app.login_as(User.find(1), scope: :user).
eloyesp
148

Una manera fácil de llamar a una acción de controlador desde un script / consola y ver / manipular el objeto de respuesta es:

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

El objeto de la aplicación es una instancia de ActionController :: Integration :: Session

Esto funciona para mí usando Ruby on Rails 2.1 y 2.3, y no probé versiones anteriores.

Mella
fuente
2
Un enlace a la documentación oficial sobre el objeto de la aplicación sería bueno.
RajaRaviVarma
Es una instancia de la clase ActionController :: Integration :: Session. He actualizado la respuesta para incluir eso.
Nick
Gran idea. No había pensado en esto.
Marnen Laibow-Koser
55
¿Cómo puedo autenticar la consola para poder verificar los controladores que requieren autenticación?
Mild Fuzz
77
Debería poder publicar en su página de inicio de sesión, algo así como: app.post '/ session / new', {: username => "foo",: password => "pass"}. Y luego continúe usando la misma variable de "aplicación" para obtener páginas después de eso.
Nick
108

Si necesita probar desde la consola (probado en Ruby on Rails 3.1 y 4.1):

Acciones del controlador de llamadas:

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

Métodos de ApplicationController:

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

Ayudantes de ruta:

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

Ver ayudantes:

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\" />"

Hacer:

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'

Métodos de ActiveSupport:

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

Módulos Lib:

> require 'my_utils'
 => true
> include MyUtils
 => Object
> MyUtils.say "hi"
evaluate: hi
 => true
Fernando Fabreti
fuente
1
Esto ayuda cuando se escriben scripts ruby ​​independientes que se ejecutarán con rails runner y necesitan llamar a métodos en el controlador de la aplicación. Gracias
CodeExpress
@CodeExpress Eso nunca debería suceder. En su lugar, coloque los métodos en un objeto de servicio y llame al servicio desde ApplicationController y su script.
Marnen Laibow-Koser
77

Aquí hay una forma de hacerlo a través de la consola:

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

La creación de una nueva instancia de ActionView::Basele da acceso a los métodos de vista normales que su ayudante probablemente usa. Luego, la extensión YourHelperModulecombina sus métodos en su objeto, lo que le permite ver sus valores de retorno.

Gordon Wilson
fuente
15

Si el método es el POSTmétodo, entonces:

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

(Aquí los parámetros serán según su aplicabilidad).

De lo contrario, si es el GETmétodo, entonces:

app.get 'controller/action'
Swapnil Chincholkar
fuente
1
Y para encontrar los caminos que desea, app.methods.grep(/_path/):)
Dorian
Y no siempre es así controler/action, depende de tus rutas, por ejemplo, podría ser /users/ally mapa para Api::UsersController#index:)
Dorian
@Dorian Or rake routes. :)
Marnen Laibow-Koser
14

Otra forma de hacer esto es usar el depurador Ruby on Rails. Hay una guía de Ruby on Rails sobre depuración en http://guides.rubyonrails.org/debugging_rails_applications.html

Básicamente, inicie el servidor con la opción -u:

./script/server -u

Y luego inserte un punto de interrupción en su script donde le gustaría tener acceso a los controladores, ayudantes, etc.

class EventsController < ApplicationController
  def index
    debugger
  end
end

Y cuando realiza una solicitud y presiona esa parte en el código, la consola del servidor devolverá un mensaje en el que podrá realizar solicitudes, ver objetos, etc. desde un símbolo del sistema. Cuando termine, simplemente escriba 'cont' para continuar la ejecución. También hay opciones para la depuración extendida, pero esto al menos debería comenzar.

Dan McNevin
fuente
3
> => Aviso: la opción del depurador se ignora desde Ruby 2.0 y se eliminará en futuras versiones.
estrella brillante
13

Aquí le mostramos cómo hacer una solicitud POST autenticada, utilizando Refinery como ejemplo:

# 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}

También puede encontrar estos útiles si obtiene un error:

app.cookies.to_hash
app.flash.to_hash
app.response # long, raw, HTML
Chloe
fuente
2
NameError: undefined local variable or method app for main:Object
Kamil Lelonek
también necesita deshabilitar forgery_protectionApplicationController.allow_forgery_protection = false
William Herry
Wow, eso es probablemente más fácil. Lo que escribí es con protección contra falsificaciones. No necesita deshabilitarlo, ¡pero estoy seguro de que es más conveniente!
Chloe
12

Puede acceder a sus métodos en la consola de Ruby on Rails de la siguiente manera:

controller.method_name
helper.method_name
Jyothu
fuente
7

Las respuestas anteriores están llamando a ayudantes, pero lo siguiente ayudará a llamar a los métodos del controlador. He usado esto en Ruby on Rails 2.3.2.

Primero agregue el siguiente código a su archivo .irbrc (que puede estar en su directorio de inicio)

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

Luego, en la consola de Ruby on Rails, puede escribir algo como ...

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

... y el HTML se volcará a la consola.

David Knight
fuente
3

Dentro de cualquier acción o vista del controlador, puede invocar la consola llamando al método de la consola .

Por ejemplo, en un controlador:

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

O en una vista:

<% console %>

<h2>New Post</h2>

Esto generará una consola dentro de su vista. No necesita preocuparse por la ubicación de la llamada de la consola; no se representará en el momento de su invocación, sino al lado de su contenido HTML.

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

Gayan Weerakutti
fuente
3

Para los controladores, puede crear una instancia de un objeto controlador en la consola de Ruby on Rails.

Por ejemplo,

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
Dyaniyal Wilson
fuente
¡Funciona! Pero, ¿cómo puedo actualizar las variables de acción? Ej: def show response = @user.contributions end ¿Cómo anulo la @uservariable?
Fábio Araújo
2

Un posible enfoque para la prueba del método Helper en la consola de Ruby on Rails es:

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

Y para recargar hacer:

reload!; Struct.new(:t).extend(YourHelper).your_method(*arg)
Dino Reic
fuente
1

Si ha agregado su propio ayudante y desea que sus métodos estén disponibles en la consola, haga lo siguiente:

  1. En la consola ejecute include YourHelperName
  2. Sus métodos de ayuda ahora están disponibles en la consola, y úselos llamando method_name(args)en la consola.

Ejemplo: digamos que tiene MyHelper (con un método my_method) en 'app / helpers / my_helper.rb`, luego en la consola haga:

  1. include MyHelper
  2. my_helper.my_method
Desarrollador Marius Žilėnas
fuente