问题描述
正在处理具有 has_many_through 连接表的项目,该连接表具有附加属性。我的模型是葡萄酒、食物,连接表是配对。我没有将所有属性参数传递给我的强参数。我尝试了几种不同的方法 - 通过食物控制器和配对控制器,但通过葡萄酒控制器似乎是最直接的途径。在 wines new 表单上,我询问有关酒的基本信息,允许用户从之前输入的所有食物中选择要配对的食物,并允许他们输入新食物并指出它是什么类型的配对(哪个是连接表上的附加属性)。从表单中,我从预先存在的食物中获取 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,: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
end
Wines_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,checked: true %>
<%= fff.label :pairing_type,"Contrasting","value" => "Contrasting" %><%= fff.radio_button :pairing_type,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","user_id"=>"1","pairings_attributes"=><ActionController::Parameters {"0"=><ActionController::Parameters {"pairing_type"=>"Congruent"} permitted: true>} permitted: true>,"2"]} permitted: true>
感谢任何见解-
解决方法
您不应该在 import socket
HOST = 'xxx.30.1.5'
PORT = 9999
client_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client_socket.connect((HOST,PORT))
Model = 'TT'
now_ENDITEM = "enditem_list_XXX.dat"
MSG = "[" + Model + "] Requests Data Update."
client_socket.send(MSG.encode())
send_MSG = client_socket.recv(1024)
print(repr(send_MSG.decode()))
client_socket.send(now_ENDITEM.encode())
while True:
# client_socket.send(message.encode())
data = client_socket.recv(1024)
print('Received from the server :',repr(data.decode()))
temp = data.decode()
if temp.startswith('enditem_list_') :
file = data.decode()
print("START : ",file)
f = open('./CLIENT\\' + file,"wb")
l = 1
while(l):
l = client_socket.recv(1024)
print('Data ---> {0}'.format(l))
while(l) :
f.write(l)
l = client_socket.recv(1024)
f.close()
client_socket.close()
模型中为 :food
使用 accepts_nested_attributes,因为您有 has_many through: 食物和酒之间的间接关系。
你应该在配对模型中使用 wine
与单数符号,即 :food
有一个look