ruby-on-rails - 嵌套资源,simple_form_for
问题描述
我正在尝试创建一个有活动的应用程序,每个活动都会有很多销售。创建新销售时,它会自动获取它所属的事件 ID。有人可以查看这个并告诉我我是否做错了什么,因为我认为为嵌套模型(Sale)创建 simple_form 的方式有点不正确。另外我不确定它是否应该这样或者我做错了什么,但是当我访问嵌套的孩子时,网址看起来像这样
.../events/4/sales/1
.../events/3/sales/1
.../events/5/sales/1
但我希望它是这样的?!
.../events/4/sales/1
.../events/4/sales/2
.../events/4/sales/3
这是我的事件控制器和模型
class Event < ApplicationRecord
has_many :sales, dependent: :destroy
end
.
class EventsController < ApplicationController
def index
@events = Event.all
end
def new
@event = Event.new
end
def create
@event = Event.new(event_params)
if @event.save
redirect_to @event
else
redirect_to events_path
end
end
def show
@event = Event.find(params[:id])
@sales = @event.sales
end
private
def event_params
params.require(:event).permit(:name, :comment, :event_disscount)
end
end
. 这是我的销售控制器和模型
class Sale < ApplicationRecord
belongs_to :event
has_many :sale_items
accepts_nested_attributes_for :sale_items, allow_destroy: true
end
.
class SalesController < ApplicationController
def new
@sale = Sale.new(event_id: params[:event_id])
@event = Event.find_by(id: params[:event_id])
end
def create
@event = Event.find(params[:event_id])
@sale = @event.sales.create(params[:sale].permit(:receipt_email))
if @sale.save
redirect_to @event
else
redirect_to new
end
end
end
路线.rb
Rails.application.routes.draw do
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
resources :events do
resources :sales
end
root 'events#index'
end
这就是我使用 simple_form 进行销售的方式(新)
<%= simple_form_for([@event, @sale]) do |f| %>
我主要关心的是销售控制器中的“新”操作,用其父级的 id 创建嵌套资源的最佳方法是什么,然后将此对象传递给 simple_form?!
先感谢您
解决方案
你的问题太笼统了。基本上你做的很好,但是,通过对代码的一些改进,可以更容易地找到可能的问题。
我创建新销售的方式是否正确?
对您的一些改进SalesController
:
创建私有方法
sale_params
,它将清理表单中的输入参数。你已经为活动做过 - 为什么不在这里做呢?由于该控制器在事件范围内工作,
params[:event_id]
因此为每个操作设置。所以创建一个before_action
过滤器来设置你的@event
变量。方法
create
将模型保存到数据库中,因此save
在它之后调用是没有意义的。如果保存
@sale
到数据库失败,重定向到new
是不合理的。在这种情况下,用户在表单中输入的所有内容都将丢失,不会显示验证错误,并且看起来像是您的应用程序的故障。使用new
相同的@sale
.
这就是我重写控制器的方式:
class SalesController < ApplicationController
before_action: :set_event
def new
@sale = @event.sales.build
end
def create
@sale = @event.sales.build(sale_params)
if @sale.save
redirect_to @event
else
render action: :new
end
end
private
def sale_params
params.require(:sale).permit(:receipt_email, sale_items_attributes: [])
end
def set_event
@event = Event.find(params[:event_id])
end
end
推荐阅读
- css - 显示块不移动到下一行
- arguments - 在 Windows 上,寻找准系统 C++ 程序来确定另一个程序在启动时的起始参数
- javascript - JS HTML CSS:在我的参数中调用 popOpen() 时遇到问题
- python-3.x - 类似于 python 中的字符串的可变数据类型
- java - 如何在我的程序中自动命名对象?(爪哇)
- ios - 如何使 Swift 包在 Objective-C 项目中可导入/可用?
- performance - 将大数据流(结构化数据)持久保存到雪花表中的最快方法
- oracle - 在 Oracle 数据库查询中,有没有办法在事务中获取共享行锁?
- perl - Perl 一次搜索和替换多个字符串
- python - 使用 python-weka-wrapper 运行 weka 时如何设置测试选项?