嵌套资源,simple_form_for

时间:2018-10-11 14:56:10

标签: ruby-on-rails ruby-on-rails-5

我正在尝试创建一个包含事件的应用程序,每个事件都会带来很多销售。创建新销售时,它将自动获取其所属的事件ID。有人可以复习一下并告诉我是否做错了,因为我认为为嵌套模型(Sale)创建simple_form的方式有些不正确。另外,我不确定是否应该采用这种方式,或者我做错了什么,但是当我访问嵌套的子级时,URL看起来像这样

.../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

routes.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| %>

我主要关心的是Sales控制器中的“新”操作,什么是创建具有其父ID的嵌套资源,然后将该对象传递给simple_form的最佳方法?!

提前谢谢

1 个答案:

答案 0 :(得分:0)

您的问题太广泛了。基本上,您做的很好,但是,通过对代码进行一些改进,可以更轻松地发现可能的问题。

  

我进行新销售的方式正确吗?

您的id有一些改进:

  1. 创建私有方法SalesController,该方法将清除表单中的输入参数。您已经为活动做好了-为什么不在这里也这样做?

  2. 由于控制器在事件范围内工作,因此为每个操作设置了sale_params。因此,创建一个params[:event_id]过滤器,它将设置您的before_action变量。

  3. 方法@event将模型保存到数据库,因此在没有意义的情况下调用create

  4. 在将save保存到数据库失败的情况下,重定向到@sale是不合理的。在这种情况下,用户在表单中键入的所有内容都将丢失,不会显示验证错误,并且看起来像是您的应用程序出现故障。改为使用相同的new渲染new模板。

这是我重写控制器的方式:

@sale