【问题标题】:Rails is not inserting recoreds into databaseRails 没有将记录插入数据库
【发布时间】:2020-02-16 18:54:28
【问题描述】:

我是 Rails 新手,在使用我的 Car 模型将新记录插入数据库时​​遇到问题。

申请如下: 我已经按照 Rails 官方网站的定义构建了文章基础教程应用程序,直到第 5.9 节

我使用设计添加了用户身份验证,并且我想添加一个模型 -cars - 与用户关联。用户拥有_许多汽车,而汽车属于用户。 这是 user.rb 模型文件:

class User < ApplicationRecord
 # Include default devise modules. Others available are:
 # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
 devise :database_authenticatable, :registerable,
     :recoverable, :rememberable, :validatable
 has_many :cars
end

cars.rb 文件是:

class Car < ApplicationRecord
belongs_to :user
end

汽车表的结构如下:

class CreateCars < ActiveRecord::Migration[6.0]
  def change
    create_table :cars do |t|
      t.string :title
      t.text :description
      t.string :img

      t.timestamps
    end
  end
end

我添加了用户关联:

class AddUserIdToCars < ActiveRecord::Migration[6.0]
  def change
    add_column :cars, :user_id, :integer
  end
end

现在,当我使用 rails 控制台时,我看到汽车表和用户表已创建,并且创建用户工作正常。

另外,当我尝试创建一辆新车时,我被重定向回我的汽车列表,并且没有加载任何内容,当我检查控制台时,我发现汽车表是空的。

汽车控制器是:

class CarsController < ApplicationController
    def index
        @cars = Car.all
    end
    def new
    end
    def show
        @car = Car.find(params[:id])
    end
    def create
        # render plain: params[:car].inspect
        @car = Car.new(car_params)
        @car.save
        redirect_to @car
    end
    private
    def car_params
        params.require(:car).permit(:title, :description, :img)
    end
end

汽车/新视图是:

<h1>Add new car</h1>

<%= form_with scope: :car,
url: cars_path,
local: true do |form| %>
  <p>
    <%= form.label :title %><br>
    <%= form.text_field :title %>
  </p>

  <p>
    <%= form.label :description %><br>
    <%= form.text_area :description %>
  </p>

    <p>
    <%= form.label :img %><br>
    <%= form.text_area :img %>
  </p>

  <p>
    <%= form.submit %>
  </p>
<% end %>
<%= link_to 'Back', cars_path %>

汽车索引视图是:

<h1>Listing cars</h1>

<table>
  <tr>
    <th>Title</th>
    <th>description</th>
    <th>Img</th>
  </tr>

  <% @cars.each do |car| %>
    <tr>
      <td><%= car.title %></td>
      <td><%= car.description %></td>
      <td><%= car.img %></td>

      <td>
      <%= link_to 'Show', car_path(car) %>
      </td>
    </tr>
  <% end %>
</table>

<%= link_to 'New Car', new_car_path %>

当我发布新车或进入索引页面时,没有错误,并且文章部分中的相同结构(我使用 rails 官方教程创建)工作正常。

当我导航到路径/汽车或提交新车时,我看到一张空桌子。 当我尝试使用 show 时,通过导航到 cars/:id,出现错误,即不存在具有此 id 的汽车 - 另一个证明没有插入记录。

我对 Rails 很陌生,所以如果没有足够的信息,我很抱歉/我分享了很多信息。如果需要更多信息,请告诉我。

我看过大多数类似主题的问题,但没有找到任何相关的答案。我看到了这个,除其他外:

Insert into Rails Database

Rails 4 not inserting values into database

Ruby on Rails not adding record to database

Rails 5: ActiveRecord not creating record

这是创建汽车的轨道日志

Started POST "/cars" for ::1 at 2019-10-20 16:46:15 +0300 Processing by CarsController#create as HTML Parameters: {"authenticity_token"=>"MZYIt+YOELCPSFbZZmammwr7LrdMWQfzlge3k/h8UftwBjqgzHHH9VqHBFHAiwXi2Ej2Y4jM2xhC/V7sil773Q==", "car"=>{"title"=>"car3", "description"=>"123123", "img"=>"123"}, "commit"=>"Save Car"} Redirected to localhost:3000/cars Completed 302 Found in 5ms (ActiveRecord: 0.0ms | Allocations: 1322

为什么文章插入却没有插入汽车,即使功能和erb文件实际上都一样?

【问题讨论】:

  • 在插入新车时向我们展示您的 Rails 日志。日志可以在log/development.log找到。
  • @sureshprasanna70 这是相关部分吗?开始 POST "/cars" for ::1 at 2019-10-20 16:46:15 +0300 Processing by CarsController#create as HTML Parameters: {"authenticity_token"=>"MZYIt+YOELCPSFbZZmammwr7LrdMWQfzlge3k/h8UftwBjqgzHHH9VqHBFHAiwXi2Ej2Y4jM2xhC// "car"=>{"title"=>"car3", "description"=>"123123", "img"=>"123"}, "commit"=>"Save Car"} 重定向到localhost:3000/cars 完成302 在 5 毫秒内找到(ActiveRecord:0.0 毫秒 | 分配:1322

标签: ruby-on-rails ruby activemodel


【解决方案1】:

看起来你在 Rails 6 上。所以,默认情况下,当 Car belongs_to :user 时,@car 上的 user_id 是必需的。但是,在您的create 操作中,您永远不会在@car 上设置user_id,因此@car 不会保存。

如果您认为保存应该有效而实际上无效,您可以随时使用save! 而不是save。如果保存不成功,该方法的 banged 版本将引发错误。

无论如何,我认为 CarsController 中的 create 操作应该看起来更像:

class CarsController < ApplicationController

  def index
    @cars = Car.all
  end

  def new
    @car = Car.new
  end

  def show
    @car = Car.find(params[:id])
  end

  def create
    @car = current_user.cars.new(car_params)
    if @car.save
      redirect_to @car
    else
      # do something else
    end
  end

  private

  def car_params
    params.require(:car).permit(:title, :description, :img)
  end

end

通过current_user.cars.newuser_id 会自动设置在新的Car 上,您应该可以保存。

在 cmets 中回答您的问题:

为什么是 current_user.cars.new(car_params) 而不是 current_user.Car.new(car_params)?为什么不需要大写 Car,就像在 Car.find 中一样?

Car 是一个类。 Car.new 调用 Car 类的 new 方法。 Car.find 调用 Car 类的 find 方法。 Car 不是current_user 上的方法。因此,current_user.Car 没有意义,应该抛出错误。

cars(当像current_user.cars 一样使用时)是Usercurrent_user 实例上的一个方法。 .cars 方法是在您执行 User has_many :cars 时创建的。您可以在Active Record Associations 指南的Methods Added by has_many 部分查看has_many 创建的所有方法的列表。

current_user.cars 返回一个ActiveRecord_Relation。当您执行 current_user.cars.new 时,您正在调用 current_user.cars 返回的 ActiveRecord_Relation 上的 new 方法。这个new 方法返回一个Car 的实例,已经设置了user_id,这就是整个事情的重点。所以:

  1. Car.new 返回一个新的Car 没有 user_id 设置,
  2. current_user.cars.new 返回一个新的Car 带有 user_id 集。

为什么是汽车?据我了解,汽车是表的参考,而不是汽车模型本身。

没有。如上所述,在这种情况下,carscurrent_user 上的一个方法,它是在您执行 User has_many :cars 时创建的,它返回一个 ActiveRecord_Relation 代表所有具有 user_idCar 实例匹配current_user.id

【讨论】:

  • 像魅力一样工作。谢谢!最后两个问题:1)为什么是 current_user.cars.new(car_params) 而不是 current_user.Car.new(car_params)?为什么不需要资本 Car,就像在 Car.find 中一样? 2)为什么是汽车?据我了解,汽车是表的参考,而不是汽车模型本身。
  • 查看更新后的答案以及对您问题的回复。
  • 再次感谢。你是救生员
猜你喜欢
  • 2015-09-10
  • 1970-01-01
  • 2013-10-31
  • 1970-01-01
  • 1970-01-01
  • 2020-08-26
  • 2014-04-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多