Come posso chiamare i metodi controller / view helper dalla console in Ruby on Rails?


442

Quando carico script/console, a volte voglio giocare con l'output di un controller o un metodo view helper.

Ci sono modi per:

  • simulare una richiesta?
  • chiamare metodi da un'istanza del controller su detta richiesta?
  • testare metodi di supporto, tramite detta istanza del controller o in altro modo?

Risposte:


479

Per chiamare gli helper, usa l' helperoggetto:

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

Se si desidera utilizzare un helper non incluso per impostazione predefinita (ad esempio perché rimosso helper :allda ApplicationController), è sufficiente includere l'helper.

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

Per quanto riguarda la gestione dei controller , cito la risposta di 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

4
Osservo che non posso eseguirne più di uno app.get(ne consegue un errore di thread). C'è un modo per svuotare il sistema ed eseguire più get?
JellicleCat,

2
Nota in Rails 3.2 questo non funziona. Avevo bisogno di chiamare url_fordalla console. Per fare questo ho fattoapp.url_for(...)
Raphael

1
Per NoMethodError: undefined method `protect_against_forgery?' for nil:NilClassdefinire una funzione chiamata protect_against_forgery?all'interno della console che ritornafalse
Sida Zhou

come posso impostare l'utente attualmente connesso?

1
@RudolfOlah Sembra che se stai usando un dispositivo (o un guardiano) puoi farlo con ActionDispatch::Integration::Session.include(Warden::Test::Helpers); Warden.test_mode! ; app.login_as(User.find(1), scope: :user).
eloyesp,

148

Un modo semplice per chiamare un'azione del controller da uno script / console e visualizzare / manipolare l'oggetto response è:

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

L'oggetto app è un'istanza di ActionController :: Integration :: Session

Questo funziona per me usando Ruby on Rails 2.1 e 2.3 e non ho provato le versioni precedenti.


2
Un collegamento alla documentazione ufficiale sull'oggetto app sarebbe buono.
RajaRaviVarma,

È un'istanza della classe ActionController :: Integration :: Session. Ho aggiornato la risposta per includerla.
Nick,

Grande idea. Non ci avevo pensato.
Marnen Laibow-Koser,

5
Come posso autenticare la console, in modo da poter controllare i controller che richiedono l'autenticazione?
Fuzz delicato

7
Dovresti essere in grado di pubblicare nella tua pagina di accesso, qualcosa come: app.post '/ session / new', {: username => "foo",: password => "pass"}. E quindi continua a utilizzare la stessa variabile "app" per ottenere pagine dopo.
Nick

108

Se è necessario eseguire il test dalla console (testato su Ruby on Rails 3.1 e 4.1):

Chiamare le azioni del controller:

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

Metodi ApplicationController:

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

Assistenti di percorso:

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

Visualizza gli aiutanti:

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

render:

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'

Metodi ActiveSupport:

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

Moduli lib:

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

1
Questo aiuta quando si scrivono script ruby ​​indipendenti che verranno eseguiti utilizzando Rails Runner e devono chiamare i metodi nel controller dell'applicazione. Grazie
CodeExpress

@CodeExpress Non dovrebbe mai accadere. Inserire invece i metodi in un oggetto servizio e chiamare il servizio sia da ApplicationController che dallo script.
Marnen Laibow-Koser

77

Ecco un modo per farlo attraverso la console:

>> 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 creazione di una nuova istanza di ActionView::Baseconsente di accedere ai normali metodi di visualizzazione utilizzati probabilmente dall'helper. Quindi l'estensione YourHelperModulemescola i suoi metodi nel tuo oggetto permettendoti di visualizzare i loro valori di ritorno.


15

Se il metodo è il POSTmetodo, allora:

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

(Qui i parametri saranno secondo la tua applicabilità.)

Altrimenti se è il GETmetodo quindi:

app.get 'controller/action'

1
E per trovare i percorsi che desideri, app.methods.grep(/_path/):)
Dorian,

E non sempre controler/action, dipende dai tuoi percorsi, ad es. Potrebbe essere /users/alle mappare a Api::UsersController#index:)
Dorian,

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

14

Un altro modo per farlo è usare il debugger di Ruby on Rails. C'è una guida di Ruby on Rails sul debug su http://guides.rubyonrails.org/debugging_rails_applications.html

Fondamentalmente, avvia il server con l'opzione -u:

./script/server -u

E quindi inserire un punto di interruzione nello script in cui si desidera avere accesso ai controller, agli helper, ecc.

class EventsController < ApplicationController
  def index
    debugger
  end
end

E quando si effettua una richiesta e si preme quella parte nel codice, la console del server restituirà un prompt in cui è possibile quindi effettuare richieste, visualizzare oggetti, ecc. Da un prompt dei comandi. Al termine, basta digitare 'cont' per continuare l'esecuzione. Esistono anche opzioni per il debug esteso, ma questo dovrebbe almeno iniziare.


3
> => Avviso: l'opzione di debugger viene ignorata da Ruby 2.0 e verrà rimossa nelle versioni future.
stella luminosa del

13

Ecco come effettuare una richiesta POST autenticata, usando come esempio la raffineria:

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

Potresti trovare utili anche questi se ricevi un errore:

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

2
NameError: undefined local variable or method app for main:Object
Kamil Lelonek,

devi anche disabilitare forgery_protectionApplicationController.allow_forgery_protection = false
William Herry il

Wow, probabilmente è più facile. Quello che ho scritto è con la protezione dalla falsificazione. Non è necessario disabilitarlo, ma sono sicuro che sia più conveniente!
Chloe,

12

Puoi accedere ai tuoi metodi nella console di Ruby on Rails come segue:

controller.method_name
helper.method_name


7

Le risposte precedenti chiamano gli helper, ma quanto segue aiuterà a chiamare i metodi del controller. L'ho usato su Ruby on Rails 2.3.2.

Per prima cosa aggiungi il seguente codice al tuo file .irbrc (che può essere nella tua home directory)

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

Quindi nella console di Ruby on Rails puoi digitare qualcosa come ...

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

... e il codice HTML verrà scaricato sulla console.


3

All'interno di qualsiasi azione o vista del controller, è possibile richiamare la console chiamando la console metodo .

Ad esempio, in un controller:

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

O in una vista:

<% console %>

<h2>New Post</h2>

Questo renderà una console all'interno della tua vista. Non è necessario preoccuparsi della posizione della chiamata della console; non verrà visualizzato al momento della sua invocazione ma accanto al contenuto HTML.

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


3

Per i controller, è possibile creare un'istanza di un oggetto controller nella console Ruby on Rails.

Per esempio,

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

Funziona! Ma come posso aggiornare le variabili di azione. Es: def show response = @user.contributions end come posso sovrascrivere la @uservariabile?
Fábio Araújo,

2

Un possibile approccio per il test del metodo Helper nella console Ruby on Rails è:

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

E per ricaricare fare:

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

1

Se hai aggiunto il tuo aiuto personale e desideri che i suoi metodi siano disponibili nella console, procedi come segue:

  1. Nella console eseguire include YourHelperName
  2. I metodi di supporto sono ora disponibili nella console e li utilizzano chiamando method_name(args)nella console.

Esempio: supponi di avere MyHelper (con un metodo my_method) in 'app / helpers / my_helper.rb`, quindi nella console fai:

  1. include MyHelper
  2. my_helper.my_method
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.