使用带有附加属性的has_many_through连接表处理连接表的项目。我的模特是葡萄酒、食物,而接合桌则是成对的。我并没有把所有的属性都传递给我的强对立面。我尝试了几种不同的方法--通过食物控制器和配对控制器,但是通过葡萄酒控制器似乎是最直接的途径。在葡萄酒新表单上,我询问有关葡萄酒的基本信息,允许用户从先前输入的所有食物中选择要与之配对的食物,并允许他们输入新的食物并指出它是什么类型的配对(这是join表上的附加属性)。从表单中,我从预先存在的食物中得到food_ids,我得到配对类型的配对属性,但我没有得到食物属性。
模型:
class Wine < ApplicationRecord
belongs_to :user
has_many :wine_tasting_notes
has_many :tasting_notes, :through => :wine_tasting_notes
has_many :pairings, inverse_of: :wine
has_many :foods, :through => :pairings
accepts_nested_attributes_for :pairings, :allow_destroy => true
accepts_nested_attributes_for :foods
def pairings_attributes=(attributes)
attributes.values.each do |att|
if !att[:food_id].blank? || !att[:food_attributes].blank?
pairing = Pairing.new(att)
pairing.wine = self
self.pairings << pairing
end
end
end
end
class Food < ApplicationRecord
has_many :pairings, inverse_of: :food
has_many :wines, :through => :pairings
accepts_nested_attributes_for :pairings, :allow_destroy => true
accepts_nested_attributes_for :wines
end
class Pairing < ApplicationRecord
belongs_to :wine
belongs_to :food
def food_attributes=(attributes)
food = Food.find_or_create_by(attributes)
self.food_id = food.id
binding.pry
end
endWines_Controller
class WinesController < ApplicationController
def index
# binding.pry
@wines = Wine.where(:user_id => current_user.id)
end
def new
# binding.pry
@wine = Wine.new
@wine.user_id = current_user.id
@pairings = @wine.pairings.build
@food = @pairings.build_food
binding.pry
end
def show
# binding.pry
@wine = Wine.find(params[:id])
end
def create
binding.pry
@wine = Wine.new(wine_params)
binding.pry
# @wine.user_id = current_user.id
if @wine.save
# binding.pry
redirect_to @wine, notice: "Successfully created Wine"
else
# binding.pry
render :new
end
end
private
def wine_params
params.require(:wine).permit(:id, :wine_name, :color, :grape, :avg_price, :acidity, :sweetness, :user_id, pairings_attributes: [:id, :pairing_type], food_ids:[],\
food_attributes: [:id, :food_name, :food_acidity, :food_sweetness])
end
end新酒
<h1>Add a Wine</h1>
<br>
<%= form_for @wine do |f| %>
<div class ="settings">
<%= f.hidden_field :user_id %>
<%= f.label :wine_name %><%= f.text_field :wine_name %>
<%= f.label :color %><%= f.text_field :color %>
<%= f.label :grape %><%= f.text_field :grape %>
<%= f.label :avg_price %><%= f.text_field :avg_price %>
<%= f.label :acidity %><%= f.text_field :acidity %>
<%= f.label :sweetness %><%= f.text_field :sweetness %>
</div>
<br>
Food Pairings:
<br>
<%= hidden_field_tag "wine[food_ids][]", nil %>
<% Food.all.each do |food| %>
<%= check_box_tag "wine[food_ids][]", food.id, @wine.food_ids.include?(food.id), id: dom_id(food) %>
<%= label_tag dom_id(food), food.food_name %><br>
<% end %>
<br>
<strong><em>To Add a New Food Pairing:</em></strong>
<br>
<%= f.fields_for :food do |ff| %>
<%= ff.hidden_field :id %>
<%= ff.label :"Food Name:" %>
<%= ff.text_field :food_name %>
<%= ff.label :"Food Acidity:" %>
<%= ff.text_field :food_acidity %>
<%= ff.label :"Food Sweetness:" %>
<%= ff.text_field :food_sweetness %>
<br>
<br>
<% end %>
<strong>Type of Pairing: </strong>
<%= f.fields_for :pairings do |fff| %>
<%= fff.label :pairing_type, "Congruent", "value" => "Congruent" %><%= fff.radio_button :pairing_type, "Congruent", checked: true %>
<%= fff.label :pairing_type, "Contrasting", "value" => "Contrasting" %><%= fff.radio_button :pairing_type, "Contrasting", checked: false %>
<% end %>
<br>
<br>
<%= f.submit %>
<% end %>一般参数当我提交表单时
[2] pry(#<WinesController>)> params
=> <ActionController::Parameters {"authenticity_token"=>"MQy7Or4AjBLi11uEFEgBVAZnCT9kgaltqMPxIZ4X2d2BnMZwshQZkUKKCAzeQzE77pycsZN7SVOiX6NsPH/Dng==", "wine"=><ActionController::Parameters {"user_id"=>"1", "wine_name"=>"Molly Dooker The Boxer", "color"=>"Red", "grape"=>"Shiraz", "avg_price"=>"29", "acidity"=>"3.6", "sweetness"=>"4", "food_ids"=>["", "1", "2"], "food"=>{"id"=>"", "food_name"=>"Duck", "food_acidity"=>"8", "food_sweetness"=>"3"}, "pairings_attributes"=>{"0"=>{"pairing_type"=>"Congruent"}}} permitted: false>, "commit"=>"Create Wine", "controller"=>"wines", "action"=>"create"} permitted: false>强仿射- wine_params
[1] pry(#<WinesController>)> wine_params
Unpermitted parameter: :food
=> <ActionController::Parameters {"wine_name"=>"Molly Dooker The Boxer", "color"=>"Red", "grape"=>"Shiraz", "avg_price"=>"29", "acidity"=>"3.6", "sweetness"=>"4", "user_id"=>"1", "pairings_attributes"=><ActionController::Parameters {"0"=><ActionController::Parameters {"pairing_type"=>"Congruent"} permitted: true>} permitted: true>, "food_ids"=>["", "1", "2"]} permitted: true>感谢你的洞察力-
发布于 2021-01-02 16:30:33
您不应该在accepts_nested_attributes模型中将:food用于has_many,因为您通过:食品和葡萄酒之间的关系(这是间接的关系)获得了has_many。
你应该在单数符号为:食物的配对模型中使用accepts_nested_attributes_for :foods。
有一个看
https://stackoverflow.com/questions/65539037
复制相似问题