Bagaimana saya bisa memanggil metode controller / view helper dari konsol di Ruby on Rails?

442

Ketika saya memuat script/console, kadang-kadang saya ingin bermain dengan output dari controller atau metode view helper.

Apakah ada cara untuk:

  • mensimulasikan permintaan?
  • memanggil metode dari instance pengontrol atas permintaan tersebut?
  • menguji metode pembantu, baik melalui instance controller tersebut atau dengan cara lain?
kch
sumber

Jawaban:

479

Untuk memanggil pembantu, gunakan helperobjek:

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

Jika Anda ingin menggunakan helper yang tidak termasuk secara default (katakanlah, karena Anda dihapus helper :alldari ApplicationController), cukup sertakan helper.

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

Sedangkan untuk berurusan dengan pengontrol , saya kutip jawaban 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
sumber
4
Saya amati bahwa saya tidak dapat mengeksekusi lebih dari satu app.get(terjadi kesalahan thread). Apakah ada cara saya bisa flush sistem dan mengeksekusi mendapat lebih banyak?
JellicleCat
2
Catatan dalam Rails 3.2 ini tidak berfungsi. Saya perlu menelepon url_fordari konsol. Untuk melakukan ini saya lakukanapp.url_for(...)
Raphael
1
Untuk NoMethodError: undefined method `protect_against_forgery?' for nil:NilClassmenentukan fungsi yang disebut protect_against_forgery?di dalam konsol yang mengembalikanfalse
Sida Zhou
bagaimana cara mengatur pengguna yang saat ini masuk?
1
@RudolfOlah Tampaknya jika Anda menggunakan perangkat (atau sipir) Anda dapat melakukannya ActionDispatch::Integration::Session.include(Warden::Test::Helpers); Warden.test_mode! ; app.login_as(User.find(1), scope: :user).
eloyesp
148

Cara mudah untuk memanggil aksi pengontrol dari skrip / konsol dan melihat / memanipulasi objek respons adalah:

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

Objek aplikasi adalah turunan dari ActionController :: Integration :: Session

Ini berfungsi untuk saya menggunakan Ruby on Rails 2.1 dan 2.3, dan saya tidak mencoba versi sebelumnya.

Nick
sumber
2
Tautan ke dokumentasi resmi tentang objek aplikasi akan bagus.
RajaRaviVarma
Ini adalah turunan dari kelas ActionController :: Integration :: Session. Saya telah memperbarui jawabannya untuk memasukkan itu.
Nick
Ide yang hebat. Saya belum memikirkan hal ini.
Marnen Laibow-Koser
5
Bagaimana saya bisa mengotentikasi konsol, sehingga saya dapat memeriksa pengontrol yang memerlukan otentikasi?
Mild Fuzz
7
Anda harus dapat memposting ke halaman login Anda, sesuatu seperti: app.post '/ session / new', {: username => "foo",: password => "pass"}. Dan kemudian terus menggunakan variabel "aplikasi" yang sama untuk mendapatkan halaman setelah itu.
Nick
108

Jika Anda perlu menguji dari konsol (diuji pada Ruby on Rails 3.1 dan 4.1):

Tindakan Kontrol Panggilan:

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

Metode ApplicationController:

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

Rute Pembantu:

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

Lihat Pembantu:

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

Memberikan:

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'

Metode ActiveSupport:

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

Modul Lib:

> require 'my_utils'
 => true
> include MyUtils
 => Object
> MyUtils.say "hi"
evaluate: hi
 => true
Fernando Fabreti
sumber
1
Ini membantu ketika Anda menulis skrip ruby ​​independen yang akan dijalankan menggunakan rails runner dan mereka perlu memanggil metode di pengontrol aplikasi. Terima kasih
CodeExpress
@ KodeExpress Itu seharusnya tidak pernah terjadi. Sebagai gantinya, letakkan metode dalam objek layanan, dan panggil layanan dari ApplicationController dan skrip Anda.
Marnen Laibow-Koser
77

Inilah salah satu cara untuk melakukan ini melalui konsol:

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

Membuat instance baru ActionView::Basememberi Anda akses ke metode tampilan normal yang kemungkinan akan digunakan pembantu Anda. Kemudian memperluas YourHelperModulemencampur metodenya ke objek Anda memungkinkan Anda melihat nilai kembali mereka.

Gordon Wilson
sumber
15

Jika metode tersebut adalah POSTmetode, maka:

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

(Di sini parameter akan sesuai dengan penerapan Anda.)

Kalau bukan itu GETmetode, maka:

app.get 'controller/action'
Swapnil Chincholkar
sumber
1
Dan untuk menemukan jalur yang Anda inginkan, app.methods.grep(/_path/):)
Dorian
Dan itu tidak selalu controler/action, tergantung pada rute Anda, misalnya bisa /users/alldan peta ke Api::UsersController#index:)
Dorian
@Dorian Or rake routes. :)
Marnen Laibow-Koser
14

Cara lain untuk melakukan ini adalah dengan menggunakan debugger Ruby on Rails. Ada panduan Ruby on Rails tentang debugging di http://guides.rubyonrails.org/debugging_rails_applications.html

Pada dasarnya, mulai server dengan opsi -u:

./script/server -u

Dan kemudian masukkan breakpoint ke skrip Anda di mana Anda ingin memiliki akses ke controller, helpers, dll.

class EventsController < ApplicationController
  def index
    debugger
  end
end

Dan ketika Anda membuat permintaan dan menekan bagian itu dalam kode, konsol server akan mengembalikan prompt di mana Anda kemudian dapat membuat permintaan, melihat objek, dll dari prompt perintah. Setelah selesai, ketikkan 'cont' untuk melanjutkan eksekusi. Ada juga opsi untuk debugging yang diperluas, tetapi ini setidaknya harus Anda mulai.

Dan McNevin
sumber
3
> => Pemberitahuan: opsi debugger diabaikan sejak Ruby 2.0 dan itu akan dihapus dalam versi yang akan datang.
terang
13

Berikut ini cara membuat permintaan POST terotentikasi, menggunakan Refinery sebagai contoh:

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

Anda mungkin menemukan ini berguna juga jika Anda mendapatkan kesalahan:

app.cookies.to_hash
app.flash.to_hash
app.response # long, raw, HTML
Chloe
sumber
2
NameError: undefined local variable or method app for main:Object
Kamil Lelonek
Anda juga perlu menonaktifkan forgery_protectionApplicationController.allow_forgery_protection = false
William Herry
Wow, itu mungkin lebih mudah. Apa yang saya tulis adalah dengan perlindungan pemalsuan. Anda tidak perlu menonaktifkannya, tapi saya yakin ini lebih nyaman!
Chloe
12

Anda dapat mengakses metode Anda di konsol Ruby on Rails seperti berikut:

controller.method_name
helper.method_name
Jyothu
sumber
7

Jawaban sebelumnya memanggil bantuan, tetapi yang berikut akan membantu memanggil metode pengontrol. Saya telah menggunakan ini di Ruby on Rails 2.3.2.

Pertama tambahkan kode berikut ke file .irbrc Anda (yang bisa di direktori home Anda)

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

Kemudian di konsol Ruby on Rails Anda dapat mengetik sesuatu seperti ...

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

... dan HTML akan dibuang ke konsol.

David Knight
sumber
3

Di dalam aksi atau tampilan pengontrol apa pun, Anda dapat memanggil konsol dengan memanggil metode konsol .

Misalnya, dalam pengontrol:

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

Atau dalam tampilan:

<% console %>

<h2>New Post</h2>

Ini akan membuat konsol di dalam tampilan Anda. Anda tidak perlu peduli dengan lokasi panggilan konsol; itu tidak akan diberikan di tempat doa tetapi di sebelah konten HTML Anda.

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

Gayan Weerakutti
sumber
3

Untuk pengontrol, Anda bisa instantiate objek pengontrol di konsol Ruby on Rails.

Sebagai contoh,

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
sumber
Berhasil! Tetapi bagaimana saya bisa memperbarui variabel tindakan. Mis: def show response = @user.contributions end Bagaimana cara mengganti @uservariabel?
Fábio Araújo
2

Salah satu pendekatan yang mungkin untuk pengujian metode Helper di konsol Ruby on Rails adalah:

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

Dan untuk memuat ulang lakukan:

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

Jika Anda telah menambahkan pembantu Anda sendiri dan Anda ingin metodenya tersedia di konsol, lakukan:

  1. Di konsol jalankan include YourHelperName
  2. Metode pembantu Anda sekarang tersedia di konsol, dan menggunakannya untuk memanggil method_name(args)konsol.

Contoh: misalkan Anda memiliki MyHelper (dengan metode my_method) di 'app / helpers / my_helper.rb`, kemudian di konsol lakukan:

  1. include MyHelper
  2. my_helper.my_method
Pengembang Marius Žilėnas
sumber