当前位置: 动力学知识库 > 问答 > 编程问答 >

How to sort some values from an array in a controller in Rails?

问题描述:

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

网友答案:

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

params[:links].values.collect

if it was an array, you'd use

params[:links].collect

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:

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

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:

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

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:

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

Now when you build your user.link object, the display_order param will be set too.

网友答案:

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.

分享给朋友:
您可能感兴趣的文章:
随机阅读: