Rails 5 - 关联对象上嵌套属性的强参数

时间:2017-06-08 16:58:06

标签: ruby-on-rails

我正在尝试为请求模型创建嵌套属性表单。

触发“创建”操作时,我的参数无法正确保存。虽然在我的控制台中,数据的结构正确,但我希望如何输入数据。

:数量属性位于RequestDrink的JoinTable模型上。

如何正确地将这些参数列入白名单?

控制台输出

Started POST "/requests" for 127.0.0.1 at 2017-06-08 12:38:40 -0400
Processing by RequestsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"3ljcH44E7ZrEXNztlgGacyA0nyumNsTX6NyMMu9N+3SY0rCRXSsj/hsg0JP8jtVfDFkcEWOWHi/VwHrgertlLg==", "request"=>{"concierge_name"=>"Alex", "concierge_number"=>"954-123-4567", "concierge_email"=>"alex@email.com", "client_name"=>"Adam", "client_number"=>"954-765-4321", "client_email"=>"adam@email.com", "hotel_employee"=>"0", "concierge_service"=>"0", "vip_promoter"=>"0", "arriving_with_client"=>"1", "client_alone"=>"0", "males"=>"", "females"=>"1", "table_minimum"=>"1000", "event_date_id"=>"1", "arrival_time(1i)"=>"2017", "arrival_time(2i)"=>"6", "arrival_time(3i)"=>"8", "arrival_time(4i)"=>"16", "arrival_time(5i)"=>"38", "drinks_attributes"=>[{"id"=>"1", "quantity"=>"1"}, {"id"=>"2", "quantity"=>""}, {"id"=>"3", "quantity"=>""}, {"id"=>"4", "quantity"=>""}],  "commit"=>"Submit"}
Completed 404 Not Found in 18ms (ActiveRecord: 0.0ms)



ActiveRecord::RecordNotFound (Couldn't find Drink with ID=1 for Request with ID=):

app/controllers/requests_controller.rb:34:in `create'

应用/模型/ request.rb

class Request < ApplicationRecord
    has_many :request_drinks
    has_many :drinks, through: :request_drinks

    accepts_nested_attributes_for :drinks
end

应用/模型/ drinks.rb

class Drink < ApplicationRecord
    has_many :request_drinks
    has_many :requests, through: :request_drinks
end

应用/模型/ request_drink.rb

class RequestDrink < ApplicationRecord
    belongs_to :request
    belongs_to :drink
end

应用/控制器/ request_controller.rb

class RequestsController < ApplicationController
  before_action :set_request, only: [:show,
                                     :edit,
                                     :update,
                                     :destroy]

  def index
    redirect_to root_path unless admin_signed_in?
    @requests = Request.search(params[:term], params[:filter], params[:page])
  end

  def show
  end

  def new
    @request = Request.new
    @drinks = Drink.active
    @chasers = Chaser.active
    @table_locations = TableLocation.active
    @event_dates = EventDate.active
  end

  def edit
  end

  def create
    @request = Request.new(request_params)
    @request.people = (@request.males || 0) + (@request.females || 0)

    @drinks = Drink.active
    @chasers = Chaser.active
    @table_locations = TableLocation.active
    @event_dates = EventDate.active

    respond_to do |format|
      if @request.save
        format.html { redirect_to thanks_path, notice: 'Request was successfully created.' }
        format.json { render :show, status: :created, location: @request }
      else
        format.html { render :new }
        format.json { render json: @request.errors, status: :unprocessable_entity }
      end
    end
  end

  def update
    respond_to do |format|
      if @request.update(request_params)
        format.html { redirect_to @request, notice: 'Request was successfully updated.' }
        format.json { render :show, status: :ok, location: @request }
      else
        format.html { render :edit }
        format.json { render json: @request.errors, status: :unprocessable_entity }
      end
    end
  end

  def destroy
    @request.destroy
    respond_to do |format|
      format.html { redirect_to requests_url, notice: 'Request was successfully destroyed.' }
      format.json { head :no_content }
    end
  end


  private

    def set_request
      @request = Request.find(params[:id])
    end

    def request_params
      params.require(:request).permit(:concierge_name,
                                      :concierge_number,
                                      :concierge_email,
                                      :client_name,
                                      :client_number,
                                      :client_email,
                                      :hotel_employee,
                                      :concierge_service,
                                      :vip_promoter,
                                      :arriving_with_client,
                                      :client_alone,
                                      :people,
                                      :males,
                                      :females,
                                      :table_minimum,
                                      :arrival_time,
                                      :comments,
                                      :event_date_id,
                                      :drinks_attributes => [:id, :quantity]
      )
    end
end

应用/视图/请求/ _form.html.erb

<%= form_with(model: request, local: true) do |f| %>
...
      <h4>Drinks</h4>
      <% @drinks.all.each do |d| %>
        <%= hidden_field_tag "request[drinks_attributes][][id]", d.id %>
        <%= number_field_tag "request[drinks_attributes][][quantity]", 0, in: 0..10 %>
        <%= d.name %>
        <br />
      <% end %>
...
<% end %>

2 个答案:

答案 0 :(得分:1)

  

:数量属性位于RequestDrink的JoinTable模型上。

然而,您使用drinks代替request_drinks。尝试更改代码以使用后者:

型号:

class Request < ApplicationRecord
  has_many :request_drinks
  has_many :drinks, through: :request_drinks

  accepts_nested_attributes_for :request_drinks
end

查看:

...
  <%= hidden_field_tag "request[request_drinks_attributes][][id]", d.id %>
  <%= number_field_tag "request[request_drinks_attributes][][quantity]", 0, in: 0..10 %>
...

控制器:

class RequestsController < ApplicationController
  # other actions

  def request_params
    params.require(:request).permit(..., :request_drinks_attributes => [:id, :quantity])
  end
end

答案 1 :(得分:0)

谢谢,这比调整我的参数更有效。这是完成的代码

应用/模型/ request.rb

class Request < ApplicationRecord
   has_many :request_drinks
   has_many :drinks, through: :requests

   accepts_nested_attributes_for :request_drinks
end

应用/控制器/ request_controller.rb

class RequestController < ApplicationRecord
...
    def request_params
      params.require(:request).permit(:concierge_name,
                                      :concierge_number,
                                      :concierge_email,
                                      :client_name,
                                      :client_number,
                                      :client_email,
                                      :hotel_employee,
                                      :concierge_service,
                                      :vip_promoter,
                                      :arriving_with_client,
                                      :client_alone,
                                      :people,
                                      :males,
                                      :females,
                                      :table_minimum,
                                      :arrival_time,
                                      :comments,
                                      :is_deleted,
                                      :approved,
                                      :attended,
                                      :event_date_id,
                                      :request_drinks_attributes => [:request_id, :drink_id, :quantity]
                                      :table_location_ids => []
      )
    end
end

应用/视图/请求/ _form.html.erb

...
<h4>Drinks</h4>
      <% @drinks.all.each do |d| %>
        <%= hidden_field_tag "request[request_drinks_attributes][][request_id]", request.id %>
        <%= hidden_field_tag "request[request_drinks_attributes][][drink_id]", d.id %>
        <%= number_field_tag "request[request_drinks_attributes][][quantity]", 0, in: 0..10 %>
        <%= d.name %>
        <br />
      <% end %>