Ruby on Rails:如何打印字符串以及它显示在哪里?

6

我知道这是一个琐碎的问题。但我已经在谷歌上搜索了很久,却找不到这个问题的简单答案。

基本上,我有一行代码在视图中,它说<%= link_to 'Run it', :method => 'doIt' %>,然后在相应的控制器中,我有以下doIt方法:

def doIt
  puts "Just do it" 
end

我希望确认一下,如果我点击“Run it”,它会输出字符串“Just do it”。我在本地主机上运行了这个程序,没有错误,但我找不到任何输出“Just do it”的地方。它既没有显示在Rails控制台中,也没有显示在Rails服务器日志中。我只是想知道puts输出字符串的位置在哪里,该如何找到它?


第二轮:这是我尝试过的……

在index.html.erb(即根目录)中添加了这一行:

<%= link_to 'Run it', :method => 'do_it' %>

在URL中,基本上只是http://localhost:3000/(因为我将路由控制器#index作为根目录)。

显示的只是一个下划线“运行”,它链接到控制器中的“do_it”方法。

在控制器中,我包括了这个方法。

def do_it
  logger.debug "Just do it"
end

当我点击'Run it'时,网址会更改为http://localhost:3000/gollum_starters?method=do_it,并且在development.log中会写入以下内容:
Started GET "/gollum_starters?method=do_it" for 127.0.0.1 at 2011-08-25 15:27:49 -0700
  Processing by GollumStartersController#index as HTML
  Parameters: {"method"=>"do_it"}
  [1m[35mGollumStarter Load (0.3ms)[0m  SELECT "gollum_starters".* FROM "gollum_starters"
Rendered gollum_starters/index.html.erb within layouts/application (3.6ms)
Completed 200 OK in 16ms (Views: 7.7ms | ActiveRecord: 0.3ms)

此外,我尝试了所有的logger.error/info/fatal/etc ...和Rails.logger.error/info/fatal/etc,但都没有在开发日志中打印出"Just do it"这一行。
@Paul:我没有触及环境文件夹或文件,我假设默认情况下创建一个新的rails应用程序时,它处于开发状态?
@Maz:是的,你说得对,我只是想测试do_it方法是否被调用。为了这样做,我只想在控制器中打印出一些东西。我想不到任何比仅仅打印一个字符串更简单的方法,但这个问题让我很痛苦。我只使用textmate,没有IDE。
第三轮:
@Paul非常感谢,但我遇到了错误。
我的路由文件现在是:
resources :gollum_starters

root :to => "gollum_starters#index"

match 'gollum_starters/do_it' => 'gollum_starters#do_it', :as => 'do_it'

我的index.html.erb现在是:

<%= link_to "Do it", do_it_path %>

我的gollum_starters_controller.rb文件

def do_it
  logger.debug 'Just do it'
end

我在这里遇到了错误:

ID为do_it的GollumStarter未找到

错误位于此处,第二行:

def show
    @gollum_starter = GollumStarter.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.xml  { render :xml => @gollum_starter }
    end
  end

我想知道为什么会路由到show页面?当我点击do_it时,它实际上跳转到localhost:3000/gollum_starters/do_it,这是正确的,但显然错误指向了show方法?


第四轮:

@Paul,我将资源:gollum_starters下移了。

root :to => "gollum_starters#index"

match 'gollum_starters/do_it' => 'gollum_starters#do_it', :as => 'do_it'

resources :gollum_starters

但是我遇到了这个错误(天啊,我想自杀)

模板丢失

在视图路径“~/project_name/app/views”中,使用{:handlers=>[:erb, :rjs, :builder, :rhtml, :rxml], :formats=>[:html], :locale=>[:en, :en]}的gollum_starters/do_it模板丢失

:/

---------- 第四轮回答 ------------

基本上,正如错误所解释的那样,没有模板(即网页)可显示,因此会抛出错误。解决方法是添加redirect_to,这种情况下我将重定向到root_url。

def do_it
  logger.debug 'Just do it'
  redirect_to(root_url)
end

现在一切正常,“Just do it”终于输出到了development.log和rails服务器控制台。

感谢Maz,Paul和Andrew的帮助。我学到了很多。


John,看下面添加的解释。你没有理解Rails中REST的核心思想,如果你理解了它,你会更喜欢Rails。祝好运 :) - Andrew
看了一下,感谢详细的解释。 - John Lee
3个回答

4
那个 link_to 并不是你想象的那样。 :method 的值是指 HTTP 方法。
摘自 ActionView::Helpers::UrlHelper 的文档:

:method - HTTP 动词的符号。支持的动词有::post、:get、:delete 和 :put。默认为 :post。

你需要在你的 routes.rb 文件中定义一个使用你的方法的路由。
# The order of routes is important as the first matched will be used
# therefore the match needs to be above 'resources :controller'
match 'controller/do_it' => 'controller#do_it', :as => 'do_it'

resources :gollum_starters # <--- This needs to be below the match or this will catch first
  • controller/do_it是要匹配的路由
  • controller#do_it是控制器后跟要使用的操作(由#分隔)
  • :as的值创建了可以在link_to中使用的路径do_it_path

您的link_to可能看起来像:

<%= link_to "Do it", do_it_path %>

为了完成一个请求的生命周期,您需要添加一个要渲染的视图

 app/views/gollum_startes/do_it.html.erb # <-- Add file 

摘要 为了将某些内容输出到日志中,这样做会造成一些混乱,但它应该会帮助您更好地了解整个生命周期。此外,本答案还可作为帮助您解决类似问题的文档。


嗨,保罗,这很有道理,但我遇到了一个错误,请看我在第三轮发布的帖子。 - John Lee
很抱歉打扰您。又出现了缺失模板错误,请看第四轮。 - John Lee
好的,我意识到问题了。没有模板显示,所以我不得不手动重定向到某个地方,我将其重定向到根目录。 - John Lee

2
你没有理解在链接上下文中“方法”的含义。
这里的“方法”指的是请求方法,它表示你要求浏览器进行的请求类型。对于像Rails这样的RESTful应用程序来说,有四种相关的请求类型:GET、POST、PUT和DELETE。这些请求类型会影响控制器对请求的响应方式。
  • GET => INDEX或SHOW
  • POST => CREATE
  • PUT => UPDATE
  • DELETE => DESTROY
Rails还有两个其他“标准”动作,NEW和EDIT。这些都是GET请求,用于向用户呈现界面。NEW提供了一个表单来POST(CREATE)一个新对象,而EDIT则提供了一个表单来PUT(UPDATE)一个现有对象。
请参阅Rails指南以了解HTTP动词与CRUD操作之间的关系。
重要的基本事情是理解,默认情况下,链接是GET请求,表单默认是POST请求。
因此,当您的链接看起来像这样时:
<%= link_to 'Run it', :method => 'do_it' %>

“...这是虚假的。并没有“do_it”这样的HTTP方法,所以你并没有触发任何操作。因为没有这样的方法,Rails实际上将其作为URL的参数传递。因此,如果您单击它,您应该会看到浏览器地址栏末尾出现?method=do_it。”
“你尝试做的事情有几个问题。首先,link_to助手需要至少两个参数:1、链接文本,2、链接的HREF。因此,您真正需要使用的是:”
link_to 'Run it', url

第二步,您需要知道要传递哪个URL以获取您的控制器操作。
请熟悉以下 Rails 约定:当引用控制器操作时,可以使用以下格式进行缩写:controller_name#controller_action。例如:pages#showarticles#index
假设您的控制器名为 ExamplesController,则可以按如下方式手动触发七个标准控制器操作:
link_to 'examples#index', '/examples'
link_to 'examples#show', '/examples/123'  # 123 is the id of a specific example
link_to 'examples#new', '/examples/new'
link_to 'examples#create', '/examples', :method => :post
link_to 'examples#edit', '/examples/123/edit'
link_to 'examples#update', '/examples/123', :method => :put
link_to 'examples#destroy', '/examples/123', :method => :delete

请注意,上述中的INDEX、SHOW、NEW和EDIT都是GET请求。您可以指定:method => :get,但这是不必要的。
为了抽象出这个过程并在需要时处理ID分配,Rails提供了path helpers
因此,使用路径助手重复上述过程,您可以使用:
link_to 'examples#index', examples_path
link_to 'examples#show', example_path( @example )
link_to 'examples#new', new_example_path
link_to 'examples#create', examples_path, :method => :post
link_to 'examples#edit', edit_example_path( @example )
link_to 'examples#update', example_path( @example ), :method => :put
link_to 'examples#destroy', example_path( @example ), :method => :delete

现在,您可以从路由器中获取这些路径帮助程序,并且它们在您的routes.rb文件中定义。如果您在该文件中定义了以下内容:
resources :examples

如果您使用的是普通的RESTful控制器,并且想要添加自定义操作,那么您需要做出一个决定:这个操作是针对该控制器处理的全部对象集合(如index)还是只针对单个特定对象(如show)。这很重要,因为这告诉路由器您正在定义的新操作是否需要作为请求的一部分接收记录ID。
如果您想要操作整个对象集合,则应定义以下内容:...然后您将获得所有上面的path_helpers。
resources :examples do
  collection do
    get 'do_it'
  end
end

如果您想仅对集合中的单个成员进行操作,可以定义如下:
resources :examples do
  member do
    get 'do_it'
  end
end

在上面的示例中,我写了“get”时,你可以使用四个动词中的任何一个——如果你想展示一个页面,通常会使用GET,如果你要提交表单,通常会使用POST。你也可以像这样简写:
resources :examples do
  get 'do_it', :on => :collection
  post 'something', :on => :member
end

更多关于定义自定义控制器操作的信息,请参见Rails指南
现在您已经定义了一个路由,您应该在终端中运行rake routes以查看新路径助手的名称。假设您添加了do_it作为集合方法,您的路径助手将是:do_it_examples_path
现在回到您的链接,如果您放置:
<%= link_to 'Do it.', do_it_examples_path %>

...然后您将触发do_it操作。当操作被触发时,您的puts通常应该呈现到服务器日志中(假设您在终端窗口中运行rails s,您应该在started GET on examples#do_it之后立即看到它...)。
现在,在浏览器中,您将获得一个缺少模板错误,因为GET请求希望呈现视图,但这是另一个问题的主题。基本上,现在您应该了解控制器操作是什么,如何访问它们。如果您想了解有关如何处理控制器操作的更多信息,请参阅指南 :)
我希望您现在明白正在发生什么。随时提问。

-1

1
不,puts不会将输出发送到STDOUT。大多数情况下,STDOUT是终端,但有时它并不是。在这种情况下,puts仍然可以工作,只是无法将内容输出到您想要的位置。在控制台中滚动的文本也会写入开发日志。您需要写入的是该日志,而不是终端。 - Maz
谢谢解释。我已经尝试了所有这些logger.(debug|info|warn|error|fatal)并检查了开发日志,但它仍然没有写入日志。我甚至在我的项目文件夹上按ctrl-shift-f,除了我在控制器中执行的logger.debug "Just do it"之外,找不到任何记录。所以基本上我点击“运行”,调用do_it方法(从doIt更改为遵循rails约定),我执行了logger.debug/info/etc ...但我检查开发日志,“Just do it”没有被写入其中。 - John Lee
有人可以帮帮我吗?这真让人沮丧,Java 有 system.out.println,JavaScript 有 console.log,可以轻松地打印输出,非常适合调试,为什么在 Rails 上打印输出如此困难呢? - John Lee
你能展示一下你尝试过的logger代码吗?你正在哪个环境下运行,例如开发环境? - Paul.s
记录器在这种情况下不是问题——他的链接没有任何作用,因为方法参数无效并被误解。 - Andrew
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接