0

I've got a rather simple setup here: A Doc model, a Publication model, and an Article model.

doc.rb

class Doc < ActiveRecord::Base
  attr_accessible :article_ids,:created_at, :updated_at, :title
  has_many :publications, dependent: :destroy
  has_many :articles, :through => :publications, :order => 'publications.position'
  accepts_nested_attributes_for :articles, allow_destroy: false
  accepts_nested_attributes_for :publications, allow_destroy: true
end

publication.rb

class Publication < ActiveRecord::Base
  attr_accessible :doc_id, :article_id, :position
  belongs_to :doc
  belongs_to :article
  acts_as_list
end

article.rb

class Article < ActiveRecord::Base
  attr_accessible :body, :issue, :name, :page, :image, :article_print, :video, :id
  has_many :publications
  has_many :docs, :through => :publications
end

The Doc form lets users select and order a number of articles:

...
<% @articles.each do |article| %>
    <span class="handle">[drag]</span> 
    <%= check_box_tag("doc[article_ids][]", article.id, @doc.articles.include?(article), :class => "article_chooser" ) %> 
    <a id="<%= article.id %>" class="name"><%= article.name %></a>
<% end %>
...

This Coffeescript saves the order on drag:

jQuery ->
  $('#sort_articles').sortable(
    axis: 'y'
    handle: '.handle'
    update: ->
      $.post($(this).data('update-url'), $(this).sortable('serialize'))
  );

And this is the sort method in docs_controller.rb:

def sort
  Article.all.each_with_index do |id, index|
    Publication.update_all({position: index + 1}, {id: id})
  end
render nothing: true
end

I've followed this sortable lists Rails cast and it all works well until I update a Doc record because re-ordering isn't saved on update. I've come to the conclusion that it's because my sortable field is on the association table (i.e., publications), but because of the way the app works it has to be.

I've been doing some research here and found this question whose answer comes close, but because I've got a Coffeescript action saving the record in the first place it doesn't work.

Any help would be excellent, I'm really stuck.

Community
  • 1
  • 1
t56k
  • 6,769
  • 9
  • 52
  • 115

1 Answers1

0

Because I struggled for a long time with this I'm putting my stupidly simple solution here. Hopefully it helps someone else.

It's as simple as deleting the old join table records on update before the changes are saved, i.e.:

docs_controller.rb

def update
  @doc = Doc.find(params[:id])
  @doc.publications.destroy_all
  respond_to do |format|
    if @doc.update_attributes(params[:doc])
      format.html { redirect_to share_url(@doc) }
      format.json { head :no_content }
    else
      format.html { render action: "edit" }
      format.json { render json: @doc.errors, status: :unprocessable_entity }
    end
  end
end

Boom.

t56k
  • 6,769
  • 9
  • 52
  • 115