首页 > 解决方案 > 有没有办法在不同的视图中使用 Rails Scaffold 数据?

问题描述

我在 rails 中生成了一个 Scaffold,其中包含有关某些植物的一些信息:名称、描述。ID。

我想在我的root "home#index"

但索引页面没有呈现,我得到了错误:

主页中的 NoMethodError #index

nil:NilClass 的未定义方法“每个”

<% @plants.each 做 |植物| % >

这是我的代码

我知道它不是“导入”我的@plants 类,那么我怎样才能将它导入到不同的视图中呢?

<table class="table">
  <tbody>
    <% @plants.each do |plant| %>
      <tr>
        <td><%= plant.plant_name %></td>
        <td><%= plant.plant_description %></td>
        <td><%= plant.plant_id %></td>
      </tr>
    <% end %>
  </tbody>
</table>

标签: ruby-on-railsruby

解决方案


你在这里把所有的概念都弄错了。Rails 脚手架命令设置模型、控制器和视图。脚手架命令不设置任何数据。您将使用该rails db:seed命令设置数据。@plants不是一个类 - 它只是脚手架将分配给的实例变量Plant.all

在 Ruby 中你可以引用一个实例变量,即使它没有被定义并且简单地得到 nil。但是当你打电话时@plants.each do |plant|你会得到一个错误,因为你打电话#each给 nil。这是 Ruby 中的一个关键问题,它往往会绊倒初学者,有时甚至是经验丰富的开发人员。

在 Rails 中,每个请求都由路由器匹配到控制器和操作(控制器上的方法)。如果要显示植物列表,则HomeController需要分配该实例变量:

class HomeController < ApplicationController
  def index
    @plants = Plant.all
  end
end

然后 Rails 将控制器的所有实例变量“提供”给视图——这被称为视图上下文

如果你想在 HomeController 和 PlantController 之间共享代码,你可以使用一个模块:

module Planted
  extend ActiveSupport::Concern

  included do
    before_action :set_plants, only: [:index]
  end

  def set_plants
    @plants = Plant.all
  end
end

class PlantsController < ApplicationController
  include Planted
  # ...
end

class HomeController < ApplicationController
  include Planted
  # ...
end

或者继承,如果它通过liskov 可替换性原则

如果要共享视图代码,请使用partials


推荐阅读