如何对 Rails 控制器中的数组中的某些值进行排序?
我有一个链接数组,我正在将其保存到数据库中。问题是记录没有按照数组的顺序保存,即 links[1] 在 links[2] 之前保存,依此类推...
这是视图文件中的示例:
<p>
<label for="links_9_label">Label</label>
<input id="links_9_name" name="links[9][name]" size="30" type="text" />
<input id="links_9_url" name="links[9][url]" size="30" type="text" />
</p>
这是我的控制器:
def create
@links = params[:links].values.collect { |link| @user.links.new(link) }
respond_to do |format|
if @links.all?(&:valid?)
@links.each(&:save!)
flash[:notice] = 'Links were successfully created.'
format.html { redirect_to(links_url) }
else
format.html { render :action => "new" }
end
end
end
谢谢提前!
阿尔弗雷德
I've got a links array that I'm saving to a database. The problem is that the records aren't saved in the order of the array ie links[1] is saved before links[2] and so on...
This is a example from the view file:
<p>
<label for="links_9_label">Label</label>
<input id="links_9_name" name="links[9][name]" size="30" type="text" />
<input id="links_9_url" name="links[9][url]" size="30" type="text" />
</p>
And this is my controller:
def create
@links = params[:links].values.collect { |link| @user.links.new(link) }
respond_to do |format|
if @links.all?(&:valid?)
@links.each(&:save!)
flash[:notice] = 'Links were successfully created.'
format.html { redirect_to(links_url) }
else
format.html { render :action => "new" }
end
end
end
Thanks in advance!
Alfred
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的链接未按顺序存储的原因是您没有按顺序将它们呈现给数据库。
-- param 对象不是一个数组,尽管在某种程度上它可能看起来像一个数组。相反,它们是一个哈希,其中键是整数。 你需要使用
你可以说这是真的,因为如果它是一个数组,
,你会使用任何时候你使用 .values 方法,键顺序是不确定的。
解决方案
我同意@pg的观点,即您在使用 db id 作为订单时应该非常小心。例如,假设您想稍后更改订单?我经常将“list_order”作为模型中的字段。
要重新排序参数并按键的顺序保存,请尝试以下操作:
添加:另请注意,键很可能以字符串形式出现,而不是整数。因此,如果您有超过 10 个,可能需要将它们按整数排序:
添加是为了响应有关保存“display_order”的评论 -
首先,向模型添加新字段:display_order 。请务必在该字段上添加索引,因为您将对其进行排序。
然后,在您的控制器中,您需要公开模型的密钥。例如这样的:
现在,当您构建 user.link 对象时,也会设置 display_order 参数。
The reason your links aren't being stored in order is that you're not presenting them to the db in order.
-- The param object is not an array, even though, to an extent it might look like one. Rather, they are a hash where the keys are integers. You can tell this is true because you need to use
if it was an array, you'd use
Any time you use .values method, the key order is indeterminate.
Solution
I agree with @p.g that you should be very careful about using db id's as an order. Eg suppose you want to change the order later? I often have 'list_order' as a field in my models.
To reorder the params, and save in order of the key, try the following:
Added: also note that the keys might well come in as strings, not integers. So if you have more than 10 of them, might be an idea to sort them as integers:
Added in response to comment about saving the "display_order" --
First, add new field to model, :display_order. Be sure to add an index on the field since you'll be sorting on it.
Then, in your controller, you need to expose the key to the model. Eg something like this:
Now when you build your user.link object, the display_order param will be set too.
更改您的架构,使其具有 display_order 列或类似的内容,并将其作为前端的隐藏输入推送。
不鼓励依赖 id 列进行排序,因为它本质上是数据库创建的任意值,大多数恰好遵循逻辑序列。为订单设置单独的列不会破坏 DRYness,因为它(从技术上讲)用于不同的目的。
Alter your schema so it has a display_order column or something similar, and have this pushed through as a hidden input on the front end.
Relying on the id column for ordering is discouraged, as it is essentially an arbitrary value created by the DB, which happens to follow a logical sequence most of the time. Having a separate column for the order won't break DRYness because it is (technically) for a different purpose.