moiristo / deep_cloneable

This gem gives every ActiveRecord::Base object the possibility to do a deep clone that includes user specified associations.
MIT License
785 stars 89 forks source link

Problem scoping associated objects #77

Closed lorenzsell closed 7 years ago

lorenzsell commented 7 years ago

I am duplicating an existing object as part of a new object creation action as follows:

@structure = @old_structure.deep_clone include: :steps

It's a document with a sequence of steps. When the form renders the steps, they are scoped as follows:

scope :ordered_steps, -> {
    order("position ASC")
}

And the form itself renders the steps as follows:

<%= f.fields_for :steps, @structure.steps.ordered_steps do |builder| %>
    <%= render 'step_fields', f: builder %>
<% end %>

When I have the scoping in there, none of the steps are rendered. When I remove the scoping, the steps show up. Is this a problem with my implementation or the gem?

Thank you.

moiristo commented 7 years ago

deep_clone will yield an unsaved object with unsaved associations. When you call ordered_steps, you implicitly ask for a database call. This will not work, since the records are not persisted. You can fix this in one of the following ways:

lorenzsell commented 7 years ago

Not sure if I'm missing something. Trying to do the sort and getting the following error:


ActionView::Template::Error (wrong number of arguments (given 1, expected 0)):
11:09:13 PM web.1    |      49: <div class="form-group">
11:09:13 PM web.1    |      50:     <ul class="structure-form-step-list">
11:09:13 PM web.1    |      51:     <% if action_name == "duplicate" %>
11:09:13 PM web.1    |      52:         <%= f.fields_for :steps, @structure.steps.sort(&:position) do |builder| %>
11:09:13 PM web.1    |      53:           <%= render 'step_fields', f: builder %>
11:09:13 PM web.1    |      54:       <% end %>
11:09:13 PM web.1    |      55:     <% else %>
11:09:13 PM web.1    |  app/views/structures/_form.html.erb:52:in `sort'
moiristo commented 7 years ago

Oh, sorry, it should be sort_by I guess. By the way, I thought of another solution that might work too. You can specify scopes in associations, which removes the need for the ordered_steps scope: has_many :steps, ->{ order(position: :asc) }

lorenzsell commented 7 years ago

oh, I didn't know you could do that. that's a neat trick and it worked. both the inline scope and sort_by(&:position) worked. But the inline makes my code cleaner, so I'm using that.

Thank you!