如何从Rails中的控制器中的数组中对某些值进行排序?

时间:2010-03-11 17:46:06

标签: ruby-on-rails arrays controller

我有一个链接数组,我将其保存到数据库中。问题是记录没有按照数组的顺序保存,即在链接[2]之前保存链接[1]等等......

这是视图文件中的一个示例:

<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

提前致谢!

阿尔弗雷德

2 个答案:

答案 0 :(得分:1)

您的链接未按顺序存储的原因是您没有按顺序将它们呈现给数据库。

- param对象不是一个数组,即使它看起来像一个数组。相反,它们是键是整数的哈希。你可以说这是真的,因为你需要使用

params[:links].values.collect

如果是数组,则使用

params[:links].collect

每次使用.values方法时,键顺序都是不确定的。

<强>解决方案

我同意@ p.g您应该非常小心使用db id作为订单。例如,假设您想稍后更改订单?我经常在模型中使用'list_order'作为字段。

要重新排序参数,并按密钥保存,请尝试以下操作:

links_param = params[:links]
ordered_keys = links_param.keys.sort
@links = ordered_keys.collect {|key| @user.links.new(links_param[key])}

补充:还要注意,键可能会以字符串形式出现,而不是整数。因此,如果您有超过10个,可能会将它们整理为整数:

ordered_keys = links_param.keys.sort{|a,b| a.to_i <=> b.to_i}

已添加以回复有关保存“display_order”的评论

首先,将新字段添加到model,:display_order。请务必在字段上添加索引,因为您将对其进行排序。

然后,在控制器中,您需要将密钥公开给模型。例如:

 links_param = params[:links]
 links_params.keys.each{|key|links_params[key][:display_order] = key.to_i}

现在,当您构建user.link对象时,也将设置display_order参数。

答案 1 :(得分:0)

更改您的架构,使其具有display_order列或类似内容,并将其作为前端的隐藏输入推送。

不鼓励依赖id列进行排序,因为它本质上是由DB创建的任意值,它恰好遵循当时的大多数的逻辑序列。为订单设置单独的列不会破坏DRYness,因为它(在技术上)用于不同的目的。