【问题标题】:NameError in Controller and View is only displaying html控制器和视图中的 NameError 仅显示 html
【发布时间】:2015-04-19 21:39:49
【问题描述】:

我昨天花了几个小时试图弄清楚这一点,休息后我仍然感到沮丧,所以我想我会问。另外,如果这篇文章很长并且我对术语的使用是业余的,很抱歉。我对编程还是很陌生。

我正在尝试使用“themoviedb”gem 制作一个 Rails 应用程序,它允许用户搜索电影数据库的 api。这是 gem 的创建者提供的一个示例项目,它使用了旧版本的 rails:https://github.com/ahmetabdi/themoviedb-example。在开始进行自己的更改之前,我正在尝试重新创建此示例应用程序,但是我遇到了 MoviesController 的问题。

这里是 MoviesController 示例:

 class MoviesController < ApplicationController
      def show
        @movie = Tmdb::Movie.detail(params[:id])
        @images = Tmdb::Movie.images(params[:id])
        @cast = Tmdb::Movie.casts(params[:id])
        @trailers = Tmdb::Movie.trailers(params[:id])
        @similar_movies = Tmdb::Movie.similar_movies(params[:id])
      end
    end

这里是 Movies#Show View 示例的一部分:

<h3>Poster</h3>
 <%= image_tag("#{@configuration.base_url}w154#{@movie.poster_path}") if @movie.poster_path %>
<h3>Facts</h3>
  Budget: $<%= number_with_delimiter(@movie.budget, :delimiter => ',') %><br />
  Revenue: $<%= number_with_delimiter(@movie.revenue, :delimiter => ',') %><br />
  Status: <%= @movie.status %><br />
  Runtime: <%= @movie.runtime %><br />

如果我尝试使用此示例代码运行我的应用程序,则会收到以下错误:

NoMethodError in Movies#show
undefined method `poster_path' for #<Hash:0x007fb615913de0>
app/views/movies/show.html.erb:5:in `_app_views_movies_show_html_erb___4006517199107153671_70210007215400'

我的解决方案是在 MoviesController 中添加一个辅助方法并重构 Movies#Show View 的代码以修复哈希元素错误:

class MoviesController < ApplicationController
  helper_method :movie

  def show
    @movie = Tmdb::Movie.detail(params[:id])
    @images = Tmdb::Movie.images(params[:id])
    @cast = Tmdb::Movie.casts(params[:id])
    @trailers = Tmdb::Movie.trailers(params[:id])
    @similar_movies = Tmdb::Movie.similar_movies(params[:id])
  end

  private 
    def movie
        @movie = Tmdb::Movie.detail(params[:id])
        images = Tmdb::Movie.images(params[:id])
    end
end

#views/movies/show.html.erb
  <h3>Poster</h3>
  <%= image_tag("#{@configuration.base_url}w154#{movie[:poster_path]}") if movie[:poster_path] %>
  <h3>Test data</h3>
  Runtime: <%= movie[:runtime] %><br />

通过进行这些更改,我可以使用正确的 ID 加载页面,但似乎没有任何 rails 命令运行,所以我最终得到一个显示 html 的页面,但没有任何拉取的信息显示出来。

当我尝试播放电影时,终端中显示的内容如下:

Started GET "/movies/329" for 127.0.0.1 at 2015-04-19 14:32:07 -0700
Processing by MoviesController#show as HTML
  Parameters: {"id"=>"329"}
  Rendered movies/show.html.erb within layouts/application (900.5ms)
  Rendered layouts/_header.html.erb (0.8ms)
  Rendered layouts/_footer.html.erb (0.2ms)
Completed 200 OK in 2083ms (Views: 1011.1ms | ActiveRecord: 0.0ms)

我认为我只是遇到了某种语法问题,但老实说我不知道​​。我想我也可能是想太多了。我的 SearchController 和视图工作正常,但我无法使用此控制器/视图获得结果。

我非常感谢任何帮助或建议来帮助我解决这个问题。

【问题讨论】:

  • 有什么问题?你有错误信息要分享吗?
  • 我实际上没有错误消息。页面加载,但视图未显示正确的内容。在上面,我的 Movies#Show 视图只显示

    元素,但 image_tag 不显示。与 代码相同。

标签: ruby-on-rails methods hash syntax controller


【解决方案1】:

在第一种情况下,当您在视图中看到以下行时:

@movie.poster_path

您得到了NoMethodError,因为@movieTmdb::Movie.detail(params[:id]) 返回的哈希,而Hash 对象没有poster_path 方法。访问它的正确方法是@movie[:poster_path],正如您在第二次尝试中几乎写的那样。

但是,您的第二次尝试不起作用,因为movie@movie 不同。当您使用在视图中创建的帮助器方法movie 时,您不会访问@movie 哈希。正如它所定义的,它返回执行的最后一行的结果,在你的情况下是

images = Tmdb::Movie.images(params[:id])

这就是movie 的值,因为它没有:poster_path 键,所以没有显示任何内容。

我相信您可以通过删除您的辅助方法并在您的视图中使用 @movie["poster_path"] 来实现此目的。不过,我之前没有使用过themoviedb gem,但我认为这就是要走的路。

更新

看起来Tmdb::Movie.detail(id) 返回的散列有字符串作为键而不是符号,它不是HashWithIndifferentAccess。应使用@movie["poster_path"] 而不是@movie[:poster_path] 访问元素。

【讨论】:

  • 对不起,我忘记了enter发送评论回复。我更改了视图,以便使用

    Test data h3> 运行时:
    .... 但是当我尝试查看详细电影页面时,这仍然不起作用。该视图仅呈现 html。这是一个非常详细的评论,我很感激。很高兴知道我试图修复它。我不确定还有什么导致问题的原因。

  • 我忘了提到我还从控制器中删除了辅助方法:)
  • 我安装了 gem 并获得了一个 API 密钥来尝试一下,我相信我知道问题出在哪里。 API 返回的哈希不使用符号作为键,而是使用字符串。 Rails 中有一种散列可以轻松处理这个问题,HashWithIndifferentAccess,但是使用字符串作为键对你来说就足够了。即:@movie["runtime"]@movie["poster_path"]
  • 那是 100% 正确的!我真的不能感谢你。感谢您为帮助我付出了多少时间和精力。谢谢!!!!!!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多