How do I call controller/view methods from the con

2019-01-01 13:53发布

When I load script/console, some times I want play with the output of a controller or a view helper method.

Are there ways to:

  • simulate a request?
  • call methods from a controller instance on said request?
  • test helper methods, either via said controller instance or another way?

13条回答
查无此人
2楼-- · 2019-01-01 14:20

An easy way to call a controller action from script/console and view/manipulate the response object is:

> 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

The app object is an instance of ActionController::Integration::Session

This works for me using Rails 2.1 and 2.3, I did not try earlier versions.

查看更多
余欢
3楼-- · 2019-01-01 14:23

To call helpers, use the helper object:

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

If you want to use a helper that's not included by default (say, because you removed helper :all from ApplicationController), just include the helper.

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

As for dealing with controllers, I quote Nick's answer:

> 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楼-- · 2019-01-01 14:24

Another way to do this is to use the rails debugger. There's a Rails Guide about debugging at http://guides.rubyonrails.org/debugging_rails_applications.html

Basically, start the server with the -u option:

./script/server -u

And then insert a breakpoint into your script where you would like to have access to the controllers/helpers/etc..

class EventsController < ApplicationController
  def index
    debugger
  end
end

And when you make a request and hit that part in the code, the server console will return a prompt where you can then make requests, view objects, etc.. from a command prompt. When finished, just type 'cont' to continue execution. There are also options for extended debugging, but this should at least get you started.

查看更多
忆尘夕之涩
5楼-- · 2019-01-01 14:32

Here is how to make an authenticated POST request, using Refinery as an example:

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

You might find these useful too if you get an error:

app.cookies.to_hash
app.flash.to_hash
app.response # long, raw, HTML
查看更多
泛滥B
6楼-- · 2019-01-01 14:33

If you need to test from the console (tested on Rails 3.1 and 4.1):

Call Controller Actions:

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

ApplicationController methods:

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

Route Helpers:

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

View Helpers:

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'

ActiveSupport methods:

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

Lib modules:

> require 'my_utils'
 => true 
> include MyUtils
 => Object 
> MyUtils.say "hi"
evaluate: hi
 => true 
查看更多
查无此人
7楼-- · 2019-01-01 14:33

Here's one way to do this through the 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>"

Creating a new instance of ActionView::Base gives you access to the normal view methods that your helper likely uses. Then extending YourHelperModule mixes its methods into your object letting you view their return values.

查看更多
登录 后发表回答