You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ruby on Rails中Create与Destroy方法失效问题求助

问题:Rails餐厅收藏应用中Create和Destroy方法失效

我是编程和Ruby on Rails新手,开发餐厅收藏应用时,Restaurant Controller的Index、Show、Update功能正常,但Create和Destroy无法工作。已排除Devise认证问题(控制器设置了skip_before_action :authenticate_user!),控制台确认无新记录创建,Create方法中加raise能看到表单参数但无法保存,Destroy也失效。


相关代码片段

数据库schema.rb

create_table "restaurants", force: :cascade do |t|
  t.string "name"
  t.string "price"
  t.string "address"
  t.string "category"
  t.string "website"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
  t.bigint "user_id"
  t.index ["user_id"], name: "index_restaurants_on_user_id"
end

模型restaurant.rb

class Restaurant < ApplicationRecord
  belongs_to :user
  CATEGORY = ['Gourmand', 'Healthy', 'Asiatique', 'Italien', 'Cuisine du monde', 'Traditionel',
              'Festive', 'Chic', 'Populaire', 'Fast-food', 'Casher', 'Halal', 'Vegan/Végétarien']

  PRICE = ['€', '€€', '€€€', '€€€€']

  validates :name, presence: true
  validates :address, presence: true
  validates :price, inclusion: { in: Restaurant::PRICE }, presence: true
  validates :category, inclusion: { in: Restaurant::CATEGORY }, presence: true
end

控制器restaurants_controller.rb

class RestaurantsController < ApplicationController
  skip_before_action :authenticate_user!
  before_action :set_restaurant, only: [:show, :edit, :update, :destroy]

  def index
    @restaurant = Restaurant.all
  end

  def show
  end

  def new
    @restaurant = Restaurant.new
  end

  def create
    @restaurant = Restaurant.new(restaurant_params)
    @restaurant.save!
    redirect_to restaurants_path(@restaurant), notice: 'new add'

    # if @restaurant.save
    #   redirect_to restaurants_path(@restaurant), notice: 'New restaurant added'
    # else
    #   render :new, status: :unprocessable_entity
    # end

  end
  def edit
  end

  def update
    @restaurant.update(restaurant_params)
    redirect_to restaurant_path(@restaurant), notice: 'Restaurant was successfully updated.'
  end

  def destroy
    @restaurant.destroy
    redirect_to restaurants_path, status: :see_other
  end

  private

  def restaurant_params
    params.require(:restaurant).permit(
      :name,
      :address,
      :category,
      :website,
      :price
    )
  end

  def set_restaurant
    @restaurant = Restaurant.find(params[:id])
  end
end

新建视图new.html.erb

<h1>Add a new restaurant </h1>
<%= render 'restaurants/form', restaurant: @restaurant %>

表单视图_form.html.erb

<%= simple_form_for(restaurant) do |f| %>
  <%= f.input :name %>
  <%= f.input :address %>
  <%= f.input :category, collection: Restaurant::CATEGORY%>
  <%= f.input :price, collection:Restaurant::PRICE %>
  <%= f.input :website%>
  <%= f.submit "#{ restaurant.persisted? ? 'Update' : 'Create' } Restaurant" %>
  <%#= link_to 'Back to restaurant', restaurants_path %>
<% end %>

问题排查与解决

1. Create方法失效的核心原因:缺少user_id关联

模型中设置了belongs_to :user,Rails默认要求该关联必须存在(即user_id不能为空)。当前Create方法未给@restaurant赋值user_id,导致验证失败,save!直接抛出异常但没有错误提示。

修复方案二选一:

  • 允许餐厅不关联用户:修改模型
    belongs_to :user, optional: true
    
  • 强制关联用户(测试阶段可手动指定,后续恢复认证后用current_user):
    def create
      # 测试用:手动指定存在的用户ID,比如1
      @restaurant = Restaurant.new(restaurant_params.merge(user_id: 1))
      # 后续恢复认证后替换为:@restaurant = current_user.restaurants.new(restaurant_params)
      if @restaurant.save
        redirect_to restaurant_path(@restaurant), notice: 'New restaurant added'
      else
        render :new, status: :unprocessable_entity
      end
    end
    

同时建议恢复if @restaurant.save分支,替换掉save!,这样验证失败时会返回表单页面,方便查看错误。

2. Destroy方法失效的排查方向

  • 检查服务器日志(rails server终端输出),查看Destroy请求的具体错误信息
  • 确认删除链接/表单的HTTP方法为DELETE:比如链接需写link_to 'Delete', restaurant_path(restaurant), method: :delete, data: { turbo_confirm: '确定删除?' }(Turbo环境下)
  • 检查是否有before_destroy回调阻止记录删除
  • 确认set_restaurant能正确找到对应ID的记录(比如ID是否存在)

额外建议

  • 在表单中添加错误提示:在_form.html.erb中加入<%= f.error_notification %>,这样能直接看到验证失败的具体原因
  • 查看服务器日志:运行rails server后,提交请求时终端会输出SQL语句和错误详情,是排查问题的关键

内容的提问来源于stack exchange,提问作者Lydia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 17:40:31