【问题标题】:Nested resources, simple_form_for嵌套资源,simple_form_for
【发布时间】:2018-10-11 14:56:10
【问题描述】:

我正在尝试创建一个有活动的应用程序,并且每个活动都会有很多销售。创建新销售时,它会自动获取它所属的事件 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 

这是我的 Events

控制器和模型
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

。 这是我的 Sales

控制器和模型
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| %>

我主要关心的是销售控制器中的“新”操作,用其父级的 id 创建嵌套资源,然后将此对象传递给 simple_form 的最佳方法是什么?!

提前谢谢你

【问题讨论】:

  • 你是如何访问嵌套子节点的?用代码更新问题
  • 几个问题。控制器的new 动作中@event.sales.build 的原因是什么?没有它,代码也能正常工作
  • 几个问题。为什么@sales = Sale.where(event_id: @event)show 行动中,当你可以做@event.sales 时?
  • when I am accessing nested children the url looks like this - 请显示您构建 URL 以访问嵌套子级的代码?
  • @IlyaKonyukhov @event.sales.build - 我不太确定我只是在尝试一些东西而忘记删除它。哦,是的,这样做更有意义@event.sales。我更新了我的问题。除了这两个变化之外,我创建新销售的方式是否正确?

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


【解决方案1】:

你的问题太笼统了。基本上你做的很好,但是对代码进行一些改进会更容易发现可能的问题。

我创建新销售的方式是否正确?

SalesController 的一些改进:

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

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

  3. 方法create将模型保存到数据库,所以在它之后调用save是没有意义的。

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

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

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

【讨论】:

  • 谢谢你,我可以看到它有多整洁和可重复使用!而且我永远不会考虑第二点,非常有帮助!
猜你喜欢
  • 1970-01-01
  • 2016-05-02
  • 2011-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多