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
相关产品推荐
相关产品推荐

