I have a rails app I'm trying to set up with sortable lists using the acts_as_list plugin. The position field in the db is getting updated, but when the page is rendered, the order is not considered. I'm looking for some help, I guess.
Here are my models...
class QuestionMembership < ActiveRecord::Base
belongs_to :form
belongs_to :question
acts_as_list
end
class Form < ActiveRecord::Base
has_many :question_memberships
has_many :questions, :through => :question_memberships
end
class Question < ActiveRecord::Base
has_many :question_memberships
has_many :forms, :through => :question_memberships
acts_as_list
end
And the sloppy view code that gives me the list...
<% @form.question_memberships.each do |qm| %>
<% q_id = "question_#{qm.id}" %>
<li class="question" id=<%= q_id %> >
<div style="color: #999; font-size: 8pt">
<%=h qm.question.content %>
</div>
</li>
<%= draggable_element(q_id, :revert=>true) %>
<% end %>
The drag and drop works for the reordering. The position value updates in the DB for the QuestionMembership objects and the page actually shows the reorder correctly. The problem is that on a page reload, it defaults back to whatever order it feels like. I think it defaults to the question id for the order instead of the question_membership position, but I'm not sure.
Any ideas on how I can make it actually order on the initial render by the position field of the QuestionMembership?
As soon as I post the question, I find the answer. I was missing the :order and :scope attributes on my models.
I was having a terrible time working this out. Up until I found this example, I had been just using acts_as_list on the "Question" model. It would work, but Rails was getting confused when I tried to create new Questions.
I tried it this way, and I could create new objects, but it seemed that my app was confused about which model the "position" field should live.
Finally, I realized that, in my case, it was completely appropriate to use just the join model as the one to have the position field on, because this is exactly what the :scope keyword was for! It scopes the ordering of "Questions" to each "Form", which may be different per form. After this, I just left off the acts_as_list from the "question" model, and dealt with sorting based on grabbing the "QuestionMembership" instances (and then using their children to display the data).
I know I'm not adding much here, but the lights came on for me, and maybe this comment will help someone else.
With Rails 2.3 you can set a default scope to always order by position:
acts_as_list :scope => <scope clause>
default_scope :order => :position
Note that this usage of scope is different than that of acts_as_list
, which decides what to scope the list to.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With