Tag: RoR

Rails + CoffeeScript + Jquery – Marking multiply objects for destruction at a time (frontend)

When we build complicated nested forms (for example with 2 or more nested resources in it), quite often we would like to add a multiply remove feature. For example to remove whole groups of resources. We can't do this by simply removing HTML form parts, because objects related to this form parts won't be deleted. Instead, Rails use a
_destroy input that should be set to true, when we want to remove an object (but the form part still needs to be sent).

<input 
  type="hidden" 
  value="false" 
  name="product[groups_attributes][0][_destroy]" 
  id="product_groups_attributes_0__destroy" 
  class="hidden"
>

It is quite easy to use when we remove one resource at a time, we can just do this:

$('#product').find( 'input:hidden' ).val(true)

Of course it is far from being perfect, but for one resource it should do the job. We don't search using _destroy, we just assume, that only the hidden field that is there is the one that we want. Bad idea

What should we do, when we have multiply hidden fields and we only want to set value for those responsible for destruction? Well, we can use a nice Jquery feature: filter with a regexp.

destroy: (node) ->
  node.hide()
  node.find('input').filter ->
    return this.id.match(/__destroy/)
  .val('true')

We get a node (this is the tree part, that we want to remove), we iterate through all the inputs and we take only those, that have an __destroy postfix in their ID. Then we set all of them to true and we hide the whole node (so user will think, that it was removed). After we send such a form, Rails will know that it should remove all objects that were marked for destruction.

Paperclip and Rspec: Stubbing Paperclip/ImageMagick to make specs run faster, but with image resolution validation

I always test my Paperclip stuff. Mostly because quite often, I need to ensure proper images resolution or other image-based conditions. Unfortunately, it takes some time, mostly because ImageMagick is performing resource consuming operations. Each resolution test needs to get valid image to determine width and height. After that, Paperclip will try to create all the thumbs and save them. This takes a lot of time! Luckily there's a Quickerclip that stubs Paperclip methods, allowing it to run faster. There's one small issue with this code: it stubs the image, so there's no way to test resolution validations. In order to make it work, but without any additional callbacks and without images converting, we need to stub two things:

First the Paperclip.run method:

# We stub some Paperclip methods - so it won't call shell slow commands
# This allows us to speedup paperclip tests 3-5x times.
module Paperclip
  def self.run cmd, params = "", expected_outcodes = 0
    cmd == 'convert' ? nil : super
  end
end

This will ignore convert command, so thumbnails won't be created on save.

Also we need to stub the Paperclip::Attachment.post_process:

class Paperclip::Attachment
  def post_process
  end
end

Don't forget to add this to your spec_helper or test_helper file!

After that, your tests/specs should run 3-5x times faster (it depends on how heavily you app is Paperclip based.

UPDATE FOR PAPERCLIP > 3.5.2
For Paperclip newer than 3.5.2 please use code presented below:

module Paperclip
  def self.run cmd, arguments = "", interpolation_values = {}, local_options = {}
    cmd == 'convert' ? nil : super
  end
end

class Paperclip::Attachment
  def post_process
  end
end

Copyright © 2024 Closer to Code

Theme by Anders NorenUp ↑