I'm having an issue writing a controller action that takes Post ids passed as a parameter and sorts them into a specific order before publishing them.
The Posts have a position
attribute (I'm using acts_as_list for sorting), and are either published or unpublished (searchable with the named_scopes Post.published
and Post.unpublished
, accordingly).
Essentially, there is a JavaScript interface that allows users to drag unpublished posts into a queue, and publish them by passing the ids as a post_ids
parameter to a controller method that looks like this:
def publish
Post.update_all(['published=?', true], :id => params[:post_ids])
redirect_to admin_path
end
Publishing the posts like this works fine. What I need to do next is to sort the Posts by their position in a specific order, and this is where I'm having problems.
Let's say a user drags post 5, then post 3, then post 7 into the queue and clicks "Publish."
What I want to do is then organize all Posts to have 5, 3, 7 at the first positions in order, and then the rest of the Post objects in the order they were already in, so sorting by Post.position would be [5, 3, 7, ...the rest of the posts in order here...]
Then if the user were to drag two new posts into the queue and click "Publish" (this time let's say posts 2 and 4), the posts should be in the order [2, 4, 5, 3, 7, ...the rest of the posts in order here...]
Then for a final example, let's say the user moves posts 10, 1, and 12 onto the queue and publishes, the order should be [10, 1, 12, 2, 4, 5, 3, 7, ...the rest of the posts in order here...]
etc...
I'd show the code I've been working on, but I'm not sure it'd be helpful since I haven't gotten it to sort correctly. But essentially I imagine this is an issue of taking two arrays, the first being all Posts and the second being the Posts to publish, and putting each item in the Posts to publish array at the beginning of the all Posts array, and then publishing. I just can't seem to get it to work. Any help here would be greatly appreciated, and I thank you in advance for your time!
Edit In case it helps, here's the code I've written so far. In testing, it seems that this method sorts the posts from the queue correctly the first time, but any subsequent posts that are published don't move to the front of the published Posts list.
def publish
if params[:to_publish].present?
# :to_publish are the posts dragged into the queue in order.
# Here I'm cleaning up the Javascript input and then iterating
# through them to update their sort order.
params[:to_publish].to_s.split(",").uniq!.each_with_index do |id, index|
Post.update_all(['position=?', index + 1], ['id=?', id])
end
end
# :post_ids are the posts to be published, order is irrelevant.
# For client-side reasons they're passed as a separate parameter.
Post.update_all(['published=?', true], :id => params[:post_ids])
redirect_to admin_path
end