Reputation: 1310
I'm learning Rails 4 by creating a simple content management system. My page structure uses the Nested Set Model and I'm trying to create a controller action so pages can be moved up and down in the page structure (i.e. left and right in the hierarchy). Here's my controller action:
# GET /admin/pages/move
def move
if params[:direction] == 'up'
ActiveRecord::Base.transaction do
@page = Page.find(params[:id])
@previous_sibling = @page.get_previous_sibling
@difference = @page.left_value - @previous_sibling.left_value
Page
.where('left_value >= :left_value AND right_value <= :right_value', {:left_value => @previous_sibling.left_value, :right_value => @previous_sibling.right_value})
.update_all('left_value = left_value + #{@difference}, right_value = right_value + #{@difference}')
Page
.where('left_value >= :left_value AND right_value <= :right_value', {:left_value => @page.left_value, :right_value => @page.right_value})
.update_all('left_value = left_value - #{@difference}, right_value = right_value - #{@difference}')
end
flash[:success] = 'The page has been moved up.'
elsif params[:direction] == 'down'
# TODO: add code to move page down
flash[:success] = 'The page was moved down.'
end
redirect_to admin_pages_path
end
The problem I'm having is the second query updates the records that have already been updated in the first query. Is there a way of effectively running both queries at once instead of one at a time so the records updated in the first query are not updated again in the second query?
Upvotes: 0
Views: 44
Reputation: 7744
Since you are updating differently in both update_all
methods, you will have to run two different queries. Either that or involve some complicated SQL code.
As for not updating the same records twice, you could check which IDs you're updating in the first go and exclude them in the second query. Here's an example (with bad variable names):
pages1 = Page.where(conditions1)
pages1_ids = pages1.pluck(:id)
pages1.update_all(update_conditions1)
pages2 = Page.where("id NOT IN (?)", pages1_ids).where(conditions2)
pages2.update_all(update_conditions2)
Upvotes: 1