【问题标题】:How to save nested attributes on a has many through relationship如何将嵌套属性保存在具有多个直通关系上
【发布时间】:2016-07-08 08:21:39
【问题描述】:

我遇到了一些问题,我对保存嵌套属性的正确方法有点困惑。

我有两个模型、位置和产品以及一个名为 stock 的连接表,用于连接这两个模型。

class Location < ApplicationRecord
  has_many :stocks
  has_many :products, :through => :stocks
end

class Product < ApplicationRecord
  has_many :stocks
  has_many :locations, :through => :stocks

  accepts_nested_attributes_for :locations
end

class Stock < ApplicationRecord
  belongs_to :location
  belongs_to :product
end

在我的控制器中,我有以下内容

class ProductsController < ApplicationController
  def index
    @products = Product.all
  end

  def new
    @product = Product.new
    @product.stocks.build
    @locations = Location.all
  end

  def create
    @product = Product.new(product_params)
    if @product.save
      flash[:notice] = "Successfully saved..."
      redirect_to products_path
    else
      flash[:alert] = "Something went wrong, please check the values you entered"
      redirect_to :back
    end
  end

但我认为我在操作上做错了,因为什么也没发生。我想要的是在创建产品时显示所有可能的位置,以便用户可以选择在哪些位置声明该产品应该存在。这自然会被库存模型跟踪。

有人愿意告诉我吗?

编辑:我对此做了一些修改,

我的新观点

<div class="input-field">
  <%= f.label :product_name %>
  <%= f.text_field :name, autofocus: true %>
</div>

<div class="input-field">
  <%= f.label :price %>
  <%= f.text_field :price, autofocus: true %>
</div>


<%= f.fields_for :stocks do |ff| %>
  <div class="input-field">
    <%= ff.collection_select :location_id, Location.all, :id, :structured_location , {:prompt => "Please Select Locations for Product"}, {multiple: true} %>
    <%= ff.label :locations %>
  </div>
<% end %>


<div class="row margin-top x-4">
  <div class="col s12 center-align">
    <%= f.submit "Update", class: "btn wave-effect pink darken-1 btn-large" %>
  </div>
</div>

在 product.rb 模型中

class Product < ApplicationRecord
  has_many :stocks
  has_many :locations, :through => :stocks

  accepts_nested_attributes_for :stocks

end

现在我可以选择位置,但是当我推送到产品控制器时,我发现 location_id 是不允许的

这是我的强大参数

def product_params
    params.require(:product).permit( :name,:price, {stocks_attributes: [:location_id]} )
  end

这是在控制台中发送的参数

Parameters: {"utf8"=>"✓", "authenticity_token"=>"751Z5I5nBwmYJwFeiXO3jyBnPxqr3Pdz0ohDpN96F0ybE9V4yeUgjt2QYDYZfNvWG4CAdhvGaxIaCmqD6Ka8qw==", "product"=>{"name"=>"Tires Cleaner", "price"=>"4", "stocks_attributes"=>{"0"=>{"location_id"=>["", "1"]}}}, "commit"=>"Update"}

【问题讨论】:

  • “什么都没有发生”是什么意思?错误?没有保存数据?等
  • 你的强参数也需要这样:params.require(:product).permit(:name,:price,locations_attributes: [:id, :venue])

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


【解决方案1】:

因为它是一个 has_many 关系,你需要告诉强参数它是你发送的一个数组,然后是位置特定的属性。此外,因此当您稍后编辑时它可以工作,我也将允许 :id 字段:

params.require(:product).permit(:name, :price, stocks_attributes: [:id, location_id: []]) 

这将允许您发布一系列场所,然后当您稍后编写更新操作时,您还可以编辑场所(如果不允许 :id,它将复制该行)。

【讨论】:

  • 嘿,我在使用这个时仍然有一个问题,它说参数 :venue 是不允许的,为什么? :S
  • 您能否使用您在铁路服务器控制台中看到的参数更新您的问题?
  • 好的,请阅读我在 EDIT 及以下的更改,谢谢
  • 我已经更新了我的答案。但是,它为 location_id 发布 ["", "1] 很奇怪,我认为表格可能有点不正确。我也会看看。
  • 嘿,这工作谢谢!但是我还有另一个“问题”。我想在数据库中创建多个库存记录,将 product_id 与各种 location_ids 链接起来,所以如果我选择两个 location_ids 来创建两个具有相同 product_id 但 location_id 不同的 Stock 记录,这可能是这种方式还是?嗯不知道有什么问题([“”,“1”])
【解决方案2】:

我认为问题在于您需要在产品参数中嵌套位置关系的属性,例如:

params.require(:product).permit(:name, :price, {stocks_attributes: [:id, :location_id]})

【讨论】:

  • 嘿,谢谢你的回答,但是我得到了和我回复 RichardAE 一样的错误......
  • @PetrosKyriakou 那是因为你的新问题与原来提出的问题完全不同,视图中的属性和关系已经完全改变,我已经编辑了我的答案。
  • 问题并没有真正改变,只是我在其他地方遇到了另一个问题,你们向我指出了。
  • 是的,我的意思是说示例代码,抱歉,哈哈,但很高兴你现在把所有内容都整理好了!
【解决方案3】:

如果位置和产品之间的关系是直接的,则更容易。我没有看到股票模型的重要性。一个位置有很多产品,一个产品有很多位置。因此,

class Location < ApplicationRecord
  has_and_belongs_to_many :products
end

class Product < ApplicationRecord
  has_and_belongs_to_many :locations
end

您需要迁移才能创建 stock 表。那么你的嵌套表单应该是`

<%= f.fields_for :locations do |ff| %>
  <div class="input-field">
    <%= ff.collection_select :id, Location.all, :id, :structured_location , {:prompt => "Please Select Locations for Product"}, {multiple: true} %>
<%= ff.label :locations %>
  </div>
<% end %>`

希望对你有帮助。

`

【讨论】:

  • 嘿,您可能会忘记的是,这样您就不能在股票表上拥有额外的字段,而我有。对不对?
  • 我以为你没有额外的字段,从你的表单中我没有看到一个
  • 是的,我忽略了他们我的坏事,谢谢你的努力;o
猜你喜欢
  • 1970-01-01
  • 2015-10-30
  • 1970-01-01
  • 1970-01-01
  • 2023-03-14
  • 2021-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多