我有以下内容
用户模型
has_many :investment_stocks
has_many :investment_prices
Investment_stock模型
belongs_to :user
has_many :investment_prices, dependent: :destroy
accepts_nested_attributes_for :investment_prices
Investment_price模型
belongs_to :investment_stock, optional: true
belongs_to :user, optional: true
但是我很难添加嵌套表单以在investment_stock和investment_price表上创建一个user_id
investment_stocks控制器
def new
@investment_stock = InvestmentStock.new
@investment_stock.investment_prices.build
end
def create
@investment_stock= InvestmentStock.new(investment_stock_params)
@investment_stock["user_id"]= current_user.id
如何使user_id同时显示在investment_stocks控制器的库存和价格表上?
在create
操作中,通过设置用户对象 itelf 来分配user_id
:
@investment_stock.user = User.find(current_user.id)
之后,当您调用@investment_stock.save()
时,您将获得设置了user_id
的两个表。
跟进您的问题,user_id如果这两个表没有user_id,您可以在下面按照以下步骤创建
创建迁移文件
rails generate migration AddUserIDToInvestmentStock
打开迁移文件,只需添加一行add_reference如下所示
class AddUserIDToInvestmentStock < ActiveRecord::Migration[5.0]
def change
add_reference :investment_stocks, :user, index: true
# this will create user_id in table investment_stocks
# although I named user field since the type is reference
# rails will create user_id
end
end
对于第二个表,我相信您可以重复上述步骤,因为它相同的步骤只是不同的表
- 如果你想了解更多关于嵌套形式的信息,Railcast第196集和第197集是很好的基础学习
所以我想你可以有几种方法来实现你在这里试图实现的目标。 一种可以在#new
操作上设置这些"不可编辑"属性。
def new
@investment_stock = InvestmentStock.new(user_id: current_user.id)
@investment_stock.investment_prices.build(user_id: current_user.id)
end
要使其端到端工作,您需要在表单中有一个隐藏字段,以维护参数哈希中的值。
- form_for @investement_stock, url: investment_stocks_url(@investement_stock) do |f|
= f.hidden_field :_method, :post
= f.hidden_field :user_id
= f.text_field :whatever_attribute
= f.fields_for :investment_prices, @investment_prices do |ip_form|
= ip_form.hidden_field :user_id
在控制器中,您应该具有请求参数,例如:
{
controller: "InvestmentStocks",
action: "create",
....
# whatever other attributes coming from the form
user_id: {some-user-id},
investment_prices_attributes: {
"0" => {
"user_id" => {some-user-id}
...
# whatever other attributes coming from the form
}
}
}
在此选项中,您将在HTML中公开用户ID - 因此任何人都可以检查它并放置另一个ID以尝试恶意操作。为了避免这种情况,请始终检查当前用户 ID 是否等于表单中发送的用户 ID,否则拒绝请求。
另一种方法是在实际尝试保留记录之前捕获参数。这意味着您可以利用请求参数并在那里设置您想要的任何内容
def create
@investment_stock = InvestmentStock.new(investment_stock_params)
if @investment_stock.save
...
else
...
end
end
private
def investment_stock_params
investment_stock_params = params[:investment_stocks].tap |stocks_attributes|
stocks_attributes["investment_prices_attributes"]["user_id"] = current_user.id
end
end
请注意,我做了一个示例,没有考虑强参数,也没有考虑当前实现中可能具有的任何其他潜在模式。因此,让我们称之为非常rails 3("旧"时尚(解决方案。但这与现在在 rails 5 中完成的方式没有什么不同。
无论如何,请务必阅读有关嵌套表单的信息。正如上面@widjajayd评论的那样,RailsCasts将极大地帮助理解这个rails功能。