如何在 Rails 应用程序的 Ruby 中将参数传递给新视图?

How to pass params to new view in Ruby on Rails app?

我正在尝试制作简单的应用程序。我在简单的 <%= form_for @data do |f| %> rails 表单中输入了我的名字和姓氏,提交后,应用程序应该呈现这样的简单文本。 My first name is <%= data.first_name %> and my last name is <%= data.last_name %>。我不知道为什么,但我的应用程序显示此错误:

undefined local variable or method `data' for

这可能是因为没有传递给视图的参数。

这是我的代码。

routes.rb

resources :data, only: [:new, :create, :index]

data_controller.rb

class DataController < ApplicationController

  def new
    @data = Data.new
  end

  def index
  end

  def create
    @data = Data.new(data_params) 

    if @data.valid?
      redirect_to @data
    else
      render :new
    end
  end

  private
    def data_params
      params.require(:data).permit(:first_name, :second_name)
    end
end

/views/data/new.html.erb

<%= form_for @data do |f| %>

    <%= f.label :first_name %>
    <%= f.text_field :first_name %>

    <%= f.label :second_name %>
    <%= f.text_field :second_name %>

    <%= f.submit 'Continue', class: 'button' %>
<% end %>

/views/data/index.html.erb

<h2>Coolest app ever :D</h2>
<p>My first name is: <%= data.first_name %>.</p>
<p>And my second name is: <%= data.second_name %>.</p>

/models/data.rb

class Data
  include ActiveModel::Model
  attr_accessor :first_name, :second_name

  validates :first_name, :second_name, presence: true 
end

请帮忙找出参数没有传递到下一页的原因。无论如何谢谢 :D

您的视图应如下所示:

<h2>Coolest app ever :D</h2>
<p>My first name is: <%= @data.first_name %>.</p>
<p>And my second name is: <%= @data.second_name %>.</p>

此外,我建议将模型称为 Data 之类的通用名称并不是非常 Rails-y 的方法。通常,领域模型对应于现实世界中的事物,例如 UserArticle,这些事物易于理解和关联。如果您需要制作另一个模型并想将其称为 Data2 或其他名称,它会很快变得混乱 :)

编辑:

既然你指定了你不想使用数据库,我建议通过重定向传递对象参数:

redirect_to(data_path(data: @data))

在你的控制器的索引方法中:

def index
  @data = Data.new(params[:data])
end

现在您的视图应该可以正确呈现,因为您将内存中的 @data 对象属性作为重定向中的参数传递。然后,您可以在索引页或您希望重定向到的任何地方重新创建该对象。


为了扩展 Matt 的回答,您收到 NilClass 错误的原因是:

当您的路由文件中没有启用 show 操作时,您将重定向到 data#show 操作。由于您已经为索引设置了视图,我假设您想在 @data 对象被验证为有效时重定向到那里:

redirect_to data_path

但是我建议您遵循 Rails 约定并在 routes.rb:

中指定 data#show 路线
resources :data, only: [:index, :new, :create, :show]

在你的 data_controller.rb:

def show
  @data = Data.find(params[:id])
end

另一个问题是您在创建 @data 对象时实际上并没有保存new 方法填充属性,valid? 在您定义的模型的指定上下文中运行所有验证,如果未发现错误,return 为 true,否则为 false。你想做这样的事情:

def create
  @data = Data.new(data_params) 

  if @data.save
    redirect_to data_path
  else
    render :new
  end
end

使用 save 尝试将记录保存到数据库,并运行验证检查 - 如果验证失败,保存命令将 return false,记录将不会被保存,并且new 模板将重新呈现。如果保存正确,控制器将重定向到索引页面,您可以在其中调用所需的特定数据对象并将其显示在视图中。