如何通过 rails 中的 form_for 标记传递嵌套模型关系
How do I pass in a nested model relationship via a form_for tag in rails
我有一个 Conversation
模型,它有一个 initiator
和一个 recipient
属性,它们都是 User
模型。
创建 form_for @conversation
时如何传递 @conversation.initiator = User.first
和 @conversation.recipient = User.third
?
class Conversation < ApplicationRecord
belongs_to :initiator, foreign_key: :initiator_id, class_name: 'User'
belongs_to :recipient, foreign_key: :recipient_id, class_name: 'User'
end
class User < ApplicationRecord
has_many :conversations
end
正如您提到的,任何对话对象都将具有发起者和接收者属性,那么它将如下所示:
def new_form
@conversation = Conversation.new(initiator: User.first, recipient: User.third)
end
现在您的两个值都可用于您的模型对象@conversation,您可以在表单的任何位置访问它,如下所示:
new.html.erb
<%= form_for @conversation do |f| %>
<%= f.text_field :body, :value => @conversation.initiator %>
<% end %>
希望对您有所帮助。
警告:
如果您正在制作一个真正的消息传递应用程序,请不要按原样使用代码。
绝不允许用户操纵敏感数据。在下面的示例中,名为 Alice 的人可以编辑隐藏字段并注入 Bob 的 ID,从而从 Bob 的帐户发送消息。
我实际上是从 devise 的 current_user
助手那里获取 Alice 的,并使用 pundit
来确保授权。
解法:
修复它,原来 hidden_field
标签第一个参数必须是 @variable
写成符号 (:variable
),第二个必须是 :attribute
然后就可以在param[:variable] #> {attribute: value}
下找到了
恕我直言,这是完成此操作的一种愚蠢且不直观的方法,但是,嘿,它有效。然后你可以对其进行强参数化并将其加载到模型中。
代码如下:
在我的控制器的 new
方法中:
# GET /conversations/new
def new
@conversation = Conversation.new
@initiator = User.first
@recipient = User.second
end
然后在new.html.erb
:
<%= form_for @conversation do |f| %>
<%= f.text_field :subject, class: "form-control" %>
<%= hidden_field :initiator, :id %>
<%= hidden_field :recipient, :id %>
<%= f.button 'Submit', class: 'btn-primary pull-right' %>
<% end %>
然后在controller的create
方法中:
def create
@conversation = Conversation.new(conversation_params)
@conversation.initiator = User.find_by(initiator_form_params)
@conversation.recipient = User.find_by(recipient_from_params)
if @conversation.save
redirect_to :back, notice: 'Conversation was successfully created.'
else
redirect_to :back, notice: 'Conversation was not sent!'
end
end
并创建强大的参数
private
def conversation_from_params
params.require(:conversation).permit(:subject)
end
def initiator_from_params
params.require(:initiator).permit(:id)
end
def recipient_from_params
params.require(:recipient).permit(:id)
end
不客气,未来的我
我有一个 Conversation
模型,它有一个 initiator
和一个 recipient
属性,它们都是 User
模型。
创建 form_for @conversation
时如何传递 @conversation.initiator = User.first
和 @conversation.recipient = User.third
?
class Conversation < ApplicationRecord
belongs_to :initiator, foreign_key: :initiator_id, class_name: 'User'
belongs_to :recipient, foreign_key: :recipient_id, class_name: 'User'
end
class User < ApplicationRecord
has_many :conversations
end
正如您提到的,任何对话对象都将具有发起者和接收者属性,那么它将如下所示:
def new_form
@conversation = Conversation.new(initiator: User.first, recipient: User.third)
end
现在您的两个值都可用于您的模型对象@conversation,您可以在表单的任何位置访问它,如下所示:
new.html.erb
<%= form_for @conversation do |f| %>
<%= f.text_field :body, :value => @conversation.initiator %>
<% end %>
希望对您有所帮助。
警告:
如果您正在制作一个真正的消息传递应用程序,请不要按原样使用代码。
绝不允许用户操纵敏感数据。在下面的示例中,名为 Alice 的人可以编辑隐藏字段并注入 Bob 的 ID,从而从 Bob 的帐户发送消息。
我实际上是从 devise 的 current_user
助手那里获取 Alice 的,并使用 pundit
来确保授权。
解法:
修复它,原来 hidden_field
标签第一个参数必须是 @variable
写成符号 (:variable
),第二个必须是 :attribute
然后就可以在param[:variable] #> {attribute: value}
恕我直言,这是完成此操作的一种愚蠢且不直观的方法,但是,嘿,它有效。然后你可以对其进行强参数化并将其加载到模型中。
代码如下:
在我的控制器的 new
方法中:
# GET /conversations/new
def new
@conversation = Conversation.new
@initiator = User.first
@recipient = User.second
end
然后在new.html.erb
:
<%= form_for @conversation do |f| %>
<%= f.text_field :subject, class: "form-control" %>
<%= hidden_field :initiator, :id %>
<%= hidden_field :recipient, :id %>
<%= f.button 'Submit', class: 'btn-primary pull-right' %>
<% end %>
然后在controller的create
方法中:
def create
@conversation = Conversation.new(conversation_params)
@conversation.initiator = User.find_by(initiator_form_params)
@conversation.recipient = User.find_by(recipient_from_params)
if @conversation.save
redirect_to :back, notice: 'Conversation was successfully created.'
else
redirect_to :back, notice: 'Conversation was not sent!'
end
end
并创建强大的参数
private
def conversation_from_params
params.require(:conversation).permit(:subject)
end
def initiator_from_params
params.require(:initiator).permit(:id)
end
def recipient_from_params
params.require(:recipient).permit(:id)
end
不客气,未来的我