如何在Ruby on Rails 3中通过表单输入设置外键?

时间:2012-02-27 16:21:04

标签: ruby-on-rails ruby forms input key

在我的新Rails应用程序中(这是我的第一个!)用户可以管理他们的客户端,并为每个客户创建项目。< / p>

Users -----< Clients -----< Projects

要为客户端创建新的项目,用户必须从以下选择框中选择客户端:

<%= f.label :client_id %>
<% options = current_user.clients.all.map { |client| [client.name, client.id] } %>
<%= f.select(:client_id, options) %>

我的控制器操作如下所示:

client = current_user.clients.find(params[:project][:client_id])
@project = client.projects.build(params[:project])

这很有效,但我觉得将client_id直接放入我的表单并不是特别好。在我的 Project 模型中,它甚至说:

attr_accessible :name, :client_id

这是一个安全漏洞吗?我不希望任何人篡改这些外键。有没有更安全的方法在Rails中设置外键?

1 个答案:

答案 0 :(得分:1)

所以Rails为这类事情提供了许多优秀的表单助手。看看这个:

http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-options_from_collection_for_select

此方法将生成您要查找的内容。要回答你的问题,没有人可以真正篡改这些ID。

如果您愿意允许用户为项目选择客户端,那么最糟糕的事情就是您有一个额外的项目,其客户与该项目无关。

以下是我如何做你想做的事情:

<%= f.select :client_id, options_from_collection_for_select(current_user.clients.all, 'id', 'name') %>

这些方法先收集colleciton(在你的情况下是current_user.clients.all),然后是选项值的属性(在你的情况下是id),然后它采用label属性(在你的情况下是名字) (客户)

你是正确的,你需要attr_accesible :client_id,但就像我说的,这确实不是一个安全问题。