Rails 4 - Cropping an Image using Jcrop, carrierwave and imagemagick

879 views Asked by At

I try the screencast #182 Cropping Images (revised) of Ryan Bates, and I do everything like the video, with a few change, because I use polymorphic model. When I try to save the cropped image, returns me to the same page, and I don't know which is my error or problem. If somebody can help me. Thanks

slide_controller.rb

class SlidesController < ApplicationController
    before_action :require_signin!, except: [:index]
    before_action :authorize_admin!, except: [:index]
    before_action :set_slide, only: [:show, :edit, :update, :destroy]

    def index
        @slide = Slide.all
    end

    def new
        @slide = Slide.new
        @slide.build_image
    end

    def create
        @slide = Slide.create(slide_params)
        @slide.user = current_user

        if @slide.save
            if params[:slide][:image_attributes].present?
                render :crop
            else
                redirect_to @slide, notice: 'Se ha guardado una nueva imagen.'
            end
        else
            flash[:alert] = 'No se guardó una nueva imagen.'

            redirect_to new_slide_path
        end
    end

    def show
    end

    def edit
    end

    def update
        if @slide.update(slide_params)
            if params[:slide][:image_attributes].present?
                render :crop
            else
                redirect_to @slide, notice: 'La imagen se ha actualizado.'
            end
        else
            flash[:alert] = 'No se actualizó la imagen.'

            render 'edit'
        end
    end

    def destroy
        @slide.destroy

        redirect_to slides_path, notice: 'La imagen se ha eliminado.'
    end

    private
        def slide_params
            params.require(:slide).permit(:title, :image_attributes => [:img_str, :crop_x, :crop_y, :crop_w, :crop_h])
        end

        def set_slide
            @slide = Slide.find(params[:id])
        end
end

image.rb

class Image < ActiveRecord::Base
    belongs_to :imageable, polymorphic: true

    mount_uploader :img_str, AssetUploader
    attr_accessor :crop_x, :crop_y, :crop_w, :crop_h
    after_update :crop_slide

    def crop_slide
        img_str.recreate_versions! if crop_x.present?
    end
end

asset_uploader.rb

class AssetUploader < CarrierWave::Uploader::Base

  include CarrierWave::RMagick

  process :resize => 0.3

  def resize(size)
    manipulate! do |img|
      img.resize(size)
    end
  end

  version :slide do
    process :crop
  end

  def crop
    if model.crop_x.present?
      manipulate! do |img|
        x = model.crop_x.to_i
        y = model.crop_y.to_i
        w = model.crop_w.to_i
        h = model.crop_h.to_i
        img.crop!(x, y, w, h)
      end
    end
  end

  storage :file

  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}"
  end

  def extension_white_list
    %w(jpg jpeg gif png)
  end
end

_form.html.erb

<%= form_for [@slide], html: { multipart: true } do |f| %>
    <% if @slide.errors.any? %>
        <div id="error_explanation">
            <h2><%= pluralize(@slide.errors.count, "error") %>
            prohiben la creación de este integrante:</h2>
            <ul>
                <% @slide.errors.full_messages.each do |msg| %>
                    <li><%= msg %></li>
                <% end %>
            </ul>
        </div>
    <% end %>

    <p>
        <%= f.label :title, 'Nombre de la imagen' %>
        <%= f.text_field :title %>
    </p>

    <%= f.fields_for :image do |image_form| %>
        <p>
            <%= image_form.label :img_str, 'Imagen' %>
            <%= image_form.file_field :img_str %>
        </p>
    <% end %>

    <%= f.submit 'Guardar' %>
<% end %>

crop.html.erb

<div class="row">
    <h1>Cortar imagen</h1>
    <%= image_tag(@slide.image.img_str, id: 'cropbox') %>


    <%= form_for [@slide] do |f| %>
        <%= f.fields_for :image do |image_form| %>
            <% %w[x y w h].each do |att| %>
                <%= image_form.text_field "crop_#{att}" %>
            <% end %>
        <% end %>

        <%= f.submit 'Cortar' %>
    <% end %>
</div>

slide.js.coffee

jQuery ->
    new SlideCropper()

class SlideCropper
    constructor: ->
        $('#cropbox').Jcrop
            aspectRadio: 32 / 13
            minSize: [1200, 520]
            maxSize: [1200, 520]
            setSelect: [0, 0, 1280, 520]
            onSelect: @update
            onChange: @update

    update: (coords) =>
        $('#slide_image_attributes_crop_x').val(coords.x)
        $('#slide_image_attributes_crop_y').val(coords.y)
        $('#slide_image_attributes_crop_w').val(coords.w)
        $('#slide_image_attributes_crop_h').val(coords.h)

Maybe I do a real mess here, but if anyone can help. I would be thankful

0

There are 0 answers