Làm cách nào tôi có thể gọi các phương thức của trình điều khiển / xem trình trợ giúp từ bảng điều khiển trong Ruby on Rails?


442

Khi tôi tải script/console, đôi khi tôi muốn chơi với đầu ra của bộ điều khiển hoặc phương thức trợ giúp xem.

Có cách nào để:

  • mô phỏng một yêu cầu?
  • gọi phương thức từ một cá thể điều khiển theo yêu cầu?
  • kiểm tra các phương thức của trình trợ giúp, thông qua thể hiện của bộ điều khiển hoặc cách khác?

Câu trả lời:


479

Để gọi người trợ giúp, sử dụng helperđối tượng:

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

Nếu bạn muốn sử dụng một trình trợ giúp không được bao gồm theo mặc định (giả sử, vì bạn đã xóa helper :allkhỏi ApplicationController), chỉ cần bao gồm trình trợ giúp.

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

Đối với việc đối phó với các bộ điều khiển , tôi trích dẫn câu trả lời của 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
Tôi quan sát rằng tôi không thể thực thi nhiều hơn một app.get(lỗi luồng xảy ra). Có cách nào để tôi có thể làm sạch hệ thống và thực thi nhiều hơn không?
JellicleCat

2
Lưu ý trong Rails 3.2, điều này không hoạt động. Tôi cần phải gọi url_fortừ bàn điều khiển. Để làm điều này tôi đã làmapp.url_for(...)
Raphael

1
Để NoMethodError: undefined method `protect_against_forgery?' for nil:NilClassxác định một chức năng được gọi protect_against_forgery?trong bảng điều khiển trả vềfalse
Sida Zhou

Làm cách nào để đặt người dùng hiện đang đăng nhập?

1
@RudolfOlah Có vẻ như nếu bạn đang sử dụng thiết bị (hoặc cai ngục), bạn có thể làm điều đó với ActionDispatch::Integration::Session.include(Warden::Test::Helpers); Warden.test_mode! ; app.login_as(User.find(1), scope: :user).
eloyesp

148

Một cách dễ dàng để gọi hành động của bộ điều khiển từ tập lệnh / bàn điều khiển và xem / thao tác đối tượng phản hồi là:

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

Đối tượng ứng dụng là một phiên bản của ActionControll :: Integration :: Session

Điều này hoạt động với tôi bằng cách sử dụng Ruby on Rails 2.1 và 2.3 và tôi đã không thử các phiên bản trước.


2
Một liên kết đến tài liệu chính thức về đối tượng ứng dụng sẽ tốt.
RajaRaviVarma

Nó là một thể hiện của lớp ActionContoder :: Integration :: Lớp phiên. Tôi đã cập nhật câu trả lời để bao gồm điều đó.
Nick

Ý tưởng tuyệt vời. Tôi đã không nghĩ về điều này.
Marnen Laibow-Koser

5
Làm cách nào để xác thực bảng điều khiển, vì vậy tôi có thể kiểm tra các bộ điều khiển yêu cầu xác thực?
Fuzz nhẹ

7
Bạn sẽ có thể đăng bài lên trang đăng nhập của mình, đại loại như: app.post '/ session / new', {: username => "foo" ,: password => "pass"}. Và sau đó tiếp tục sử dụng cùng một biến "ứng dụng" để lấy các trang sau đó.
Nick

108

Nếu bạn cần kiểm tra từ bảng điều khiển (đã thử nghiệm trên Ruby on Rails 3.1 và 4.1):

Thao tác điều khiển cuộc gọi:

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

Các phương thức của Trình điều khiển ứng dụng:

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

Người trợ giúp tuyến đường:

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

Xem người trợ giúp:

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

Kết xuất:

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'

Các phương thức ActiveSupport:

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

Mô-đun Lib:

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

1
Điều này giúp khi bạn đang viết các tập lệnh ruby ​​độc lập sẽ được chạy bằng cách sử dụng trình chạy rails và chúng cần gọi các phương thức trong bộ điều khiển ứng dụng. Cảm ơn
CodeExpress 15/03/2015

@CodeExpress Điều đó không bao giờ nên xảy ra. Thay vào đó, hãy đặt các phương thức trong một đối tượng dịch vụ và gọi dịch vụ từ cả ApplicationContoder và tập lệnh của bạn.
Marnen Laibow-Koser

77

Đây là một cách để làm điều này thông qua bảng điều khiển:

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

Tạo một phiên bản mới ActionView::Basecung cấp cho bạn quyền truy cập vào các phương thức xem bình thường mà người trợ giúp của bạn có thể sử dụng. Sau đó, mở rộng YourHelperModuletrộn các phương thức của nó vào đối tượng của bạn cho phép bạn xem các giá trị trả về của chúng.


15

Nếu phương thức là POSTphương thức thì:

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

(Ở đây các tham số sẽ theo khả năng ứng dụng của bạn.)

Khác nếu đó là GETphương pháp thì:

app.get 'controller/action'

1
Và để tìm những con đường bạn muốn, app.methods.grep(/_path/):)
Dorian

Và không phải lúc nào cũng vậy controler/action, tùy thuộc vào tuyến đường của bạn, ví dụ có thể /users/allvà ánh xạ tới Api::UsersController#index:)
Dorian

@Dorian Hoặc rake routes. :)
Marnen Laibow-Koser 23/07/19

14

Một cách khác để làm điều này là sử dụng trình gỡ lỗi Ruby on Rails. Có hướng dẫn về Ruby on Rails về gỡ lỗi tại http://guides.rubyonrails.org/debugging_rails_appluggest.html

Về cơ bản, khởi động máy chủ với tùy chọn -u:

./script/server -u

Và sau đó chèn một điểm dừng vào tập lệnh của bạn, nơi bạn muốn có quyền truy cập vào bộ điều khiển, người trợ giúp, v.v.

class EventsController < ApplicationController
  def index
    debugger
  end
end

Và khi bạn thực hiện một yêu cầu và nhấn phần đó trong mã, bảng điều khiển máy chủ sẽ trả về một dấu nhắc nơi bạn có thể thực hiện yêu cầu, xem các đối tượng, v.v. từ dấu nhắc lệnh. Khi kết thúc, chỉ cần gõ 'cont' để tiếp tục thực hiện. Ngoài ra còn có các tùy chọn để gỡ lỗi mở rộng, nhưng điều này ít nhất sẽ giúp bạn bắt đầu.


3
> => Lưu ý: tùy chọn trình gỡ lỗi bị bỏ qua kể từ Ruby 2.0 và nó sẽ bị xóa trong các phiên bản trong tương lai.
ngôi sao sáng

13

Dưới đây là cách thực hiện một yêu cầu POST được xác thực, sử dụng Nhà máy lọc dầu làm ví dụ:

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

Bạn cũng có thể thấy những điều này hữu ích nếu bạn gặp lỗi:

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

bạn cũng cần vô hiệu hóa rèn luyện_protectionApplicationController.allow_forgery_protection = false
William Herry

Wow có lẽ dễ dàng hơn. Những gì tôi đã viết là với sự bảo vệ giả mạo. Bạn không cần phải tắt nó, nhưng tôi chắc chắn rằng nó thuận tiện hơn!
Chloe

12

Bạn có thể truy cập các phương thức của mình trong bảng điều khiển Ruby on Rails như sau:

controller.method_name
helper.method_name


7

Các câu trả lời trước đó đang gọi người trợ giúp, nhưng sau đây sẽ giúp gọi các phương thức điều khiển. Tôi đã sử dụng điều này trên Ruby on Rails 2.3.2.

Trước tiên, thêm mã sau vào tệp .irbrc của bạn (có thể có trong thư mục chính của bạn)

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

Sau đó, trong bảng điều khiển Ruby on Rails, bạn có thể nhập một cái gì đó như ...

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

... Và HTML sẽ được đưa vào bảng điều khiển.


3

Trong bất kỳ hành động hoặc khung nhìn nào của bộ điều khiển, bạn có thể gọi bàn điều khiển bằng cách gọi phương thức bàn điều khiển .

Ví dụ: trong bộ điều khiển:

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

Hoặc trong một khung nhìn:

<% console %>

<h2>New Post</h2>

Điều này sẽ khiến một giao diện điều khiển trong chế độ xem của bạn. Bạn không cần quan tâm đến vị trí của cuộc gọi giao diện điều khiển; nó sẽ không được hiển thị tại chỗ của yêu cầu của nó mà bên cạnh nội dung HTML của bạn.

Xem: http://guides.rubyonrails.org/debugging_rails_appluggest.html


3

Đối với bộ điều khiển, bạn có thể khởi tạo một đối tượng điều khiển trong bảng điều khiển Ruby on Rails.

Ví dụ,

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

Nó hoạt động! Nhưng làm thế nào tôi có thể cập nhật các biến hành động. Vd: def show response = @user.contributions end Làm thế nào để tôi ghi đè @userbiến?
Fábio Araújo

2

Một cách tiếp cận khả thi để thử nghiệm phương thức Helper trong bảng điều khiển Ruby on Rails là:

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

Và để tải lại làm:

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

1

Nếu bạn đã thêm trình trợ giúp của riêng mình và bạn muốn các phương thức của nó có sẵn trong bảng điều khiển, hãy làm:

  1. Trong giao diện điều khiển thực thi include YourHelperName
  2. Phương thức trợ giúp của bạn hiện có sẵn trong bảng điều khiển và sử dụng chúng gọi method_name(args)trong bảng điều khiển.

Ví dụ: giả sử bạn có MyHelper (có phương thức my_method) trong 'app / helpers / my_helper.rb`, sau đó trong bảng điều khiển làm:

  1. include MyHelper
  2. my_helper.my_method
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.