Rails 4 在视图或模板中传递变量

Posted

技术标签:

【中文标题】Rails 4 在视图或模板中传递变量【英文标题】:Rails 4 passing variables in the views or templates 【发布时间】:2014-10-12 12:30:55 【问题描述】:

我有一个应用程序允许所有者(但不是公共用户)上传相册文件和照片。在编写视图时,我注意到一些奇怪的事情。在我的相册/index.html.erb 文件中的 do 块中,如果我传入变量 @album.id,我会得到 NilClass 的 NoMethodError。但是,如果我删除“ @",(或完全删除该变量),它工作正常。

但在我的专辑/show.html.erb 文件中,在用于编辑专辑标题的代码的 link_to 行中,我需要传递“@album.id”(或完全省略变量)以便它工作。

为什么会这样?

这是我的相册/index.html.erb 文件和代码

    <div class="admin_login"><%= link_to "Admin Login", new_album_path %></div>
    <div class="home"><%= link_to "Home", root_path %></div>

    <h1>Albums Gallery</h1>

    <% @albums.each do |album| %>
      <div>
        <%= link_to album.name, album_path(album.id) %>    
      </div>
    <% end %>

这是我的专辑/show.html.erb 文件:

<h3><%= link_to @album.name %></h3>
<div class="album">
  <%= link_to "Edit", edit_album_path(@album.id) %>
  <%= link_to "Delete", @album, method: :delete, data:confirm: "Are you sure you want to    delete this album? All photos in it will be permanently deleted!" %>
</div>
<br><%= link_to "Back", albums_path %>

为清楚起见,这是我的相册控制器代码:

    class AlbumsController < ApplicationController
      def index
        @albums = Album.all
      end

      def new
        @album = Album.new
      end

      def create
        @album = Album.new(album_params)
        @album.save
        redirect_to albums_path
      end

      def show
        @album = Album.find(params[:id])
      end

      def edit
        @album = Album.find(params[:id])    
      end

      def update
        @album = Album.find(params[:id])
          if @album.update(album_params)
            redirect_to album_path(@album.id)
          else
           render 'edit'
          end
      end

      def destroy
        @album = Album.find(params[:id])
        @album.destroy
        redirect_to albums_path
      end

      private

      def album_params
        params.require(:album).permit(:id, :name, :category)
      end
    end

【问题讨论】:

注意:如果我在 index.html.erb 文件的 do 块中完全省略 (album.id) 并且如果我还完全省略了 show.html.erb 文件中 link_to "Edit" 代码中的 (@album.id)。所以这激发了我的好奇心。 【参考方案1】:

在您的索引操作中,您将一系列专辑定义为@albums。在你的表演动作中,你只定义了一个@album。这些变量只能在定义它们的操作中访问。

'album' 在索引视图中起作用的原因是每个块都在块的范围内定义了一个本地'album' 变量。

<% @albums.each do |album| %>
  <div>
    <%= link_to album.name, album_path(album.id) %>    
  </div>
<% end %>

在 do 块之后的 |album| 说“对于这次迭代,将当前值分配给变量 album

【讨论】:

我有点明白,但我仍然对如果我从 &lt;%= link_to album.name, album_path(album.id) %&gt; 代码行中删除 (album.id) 和如果我分别从 &lt;%= link_to "Edit", edit_album_path(@album.id) %&gt; 代码行中删除 (@album.id) 。我的意思是,完全删除这些变量后,该应用程序仍然可以运行。这对我来说没有意义,为什么应该这样做。还是因为 Rails 的多态性?【参考方案2】:

您需要在控制器中设置实例变量。确保在 AlbumsController 索引操作中设置@album,在显示操作中设置@album。 do 块使用块变量,而不是实例,因此不需要@。

【讨论】:

我已经这样做了。如果我不这样做,它可能根本行不通。 忽略我回答的第一部分,我发现你的代码没有问题。

以上是关于Rails 4 在视图或模板中传递变量的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Rails 视图中将 Ruby 变量传递给 JavaScript 函数?

在视图中传递类名(rails)

如何在Rails视图中将Ruby变量传递给JavaScript函数?

通过 Django 模板中的视图传递变量

Django - 将变量从基于类的视图传递到模板

渲染 Marionette/Backbone 视图时将变量传递到 Handlebars 模板