Paperclip wariuje w trybie innym niż development

Moja aplikacja tworzy z oryginalnej fotki (objekt Foto) miniaturki (obiekt Version) w wybranym formacie.

Tworzę pierwszą w formacie np 150x200 i otrzymuję:
/system/photo_crops/16/crop/starszy.jpg?1269553079
Trzoę drugą w formacie 300x100 i otrzymuję:
/system/photo_crops/17/crop/starszy.jpg?1269553095

Po czym okazuje się że druga to dokładnie kopia pierwszej miniatury (ten sam plik w rozdzielczości 150x200 zamiast 300x100).

W trybie development wszystko jest ok. Zachodzi tylko po przełączeniu w test lub production.

Czy ktoś miał podobny problem?

hm,
strzelam, że to coś związane z cache classes. spróbuj wyłączyć to w trybie production (w production.rb config.cache_classes = false) i zobacz co się stanie.
może wrzuć też kod odpowiedzialny za robienie miniaturki.

Dzięki!

To rzeczywiście kwestia config.cache_classes = false.

Tylko teraz pewnie ucierpi wydajność.

Oto cały kod generujący miniaturki (wersje):[code=ruby]class Version < ActiveRecord::Base

attr_accessor :crop_x, :crop_y, :crop_w, :crop_h

hobo_model # Don’t put anything above this

fields do
podpis :string
caption :string
timestamps
end

belongs_to :foto
belongs_to :resolution, :class_name => “VersionDefinition”

before_update :reprocess_photo, :if => :cropping?
before_create :clone_photo, :if => :crop_auto?

has_attached_file :photo_crop,
:styles => { :thumb => “100x100”,
:crop => Proc.new { |instance| instance.crop_format },
:original => { :geometry => Proc.new { |instance| instance.foto_format },
:processors => [:cropper] },
},
:convert_options => { :crop => Proc.new { |instance| instance.crop_options } }

— Paperclip —

def ratio
resolution.width.to_f / resolution.height.to_f
end

def clone_photo
self.photo_crop = foto.photo
end

def foto_format
“#{foto.photo.styles[:big][:geometry]}”
end

def crop_format
if cropping?
“#{crop_resolution}”
else
“#{crop_resolution}>”
end
end

def crop_options
“-background white -gravity center -extent #{crop_resolution}” if resolution.crop == :auto
end

def crop_resolution
“#{resolution.width}x#{resolution.height}”
end

def cropping?
crop_x.present? && crop_y.present? && crop_w.present? && crop_h.present?
end

def crop_auto?
resolution.crop == :auto
end

def reprocess_photo
clone_photo unless photo_crop.file?
end
end[/code]
Oraz procesor:[code=ruby]module Paperclip
class Cropper < Thumbnail
def transformation_command
if crop_command
crop_command + super.sub(/ -crop \S+/, ‘’)
else
super
end
end

def crop_command
  target = @attachment.instance
  if target.cropping?
    " -crop '#{target.crop_w}x#{target.crop_h}+#{target.crop_x}+#{target.crop_y}'"
  end
end

end
end[/code]

mógłbyś jeszcze dorzucić do całość kawałek kontrolera, z metodą odpowiedzialną za dodawanie pliku?

a bez cache_classes to niestety można zapomnieć o produkcji :wink:

[code=ruby]class VersionsController < ApplicationController

hobo_model_controller

auto_actions :all, :except => :index
auto_actions_for :foto, [:new, :create]

def create_for_foto
@version = Version.new(params[:version])
if @version.save
if @version.resolution.crop == :manual
render :action => ‘crop’
else
flash[:notice] = ‘Successfully created version’
redirect_to @version
end
else
render :action => ‘new’
end
end

def update
@version = Version.find(params[:id])
if @version.update_attributes(params[:version])
if @version.photo_crop.file?
flash[:notice] = ‘Successfully updated version’
redirect_to @version
else
render :action => ‘crop’
end
else
render :action => ‘edit’
end
end
end[/code]
Do NEW/CREATE są standardowe widoki i tam pojawia się błąd (:auto nie wchodzi w CROP):

Widok (to DRYML więc może niewiele Ci powie) do akcji CROP jest nieco inny:[code]
content:

Crop


<section class="content-body">

  <%= image_tag @version.foto.photo.url(:big), :id => "cropbox" %>

  <h4>Preview:</h4>
  <div style="width:<%= @version.resolution.width %>px; height:<%= @version.resolution.height %>px; overflow:hidden">
    <%= image_tag @version.foto.photo.url(:big), :id => "preview" %>
  </div>

  <% form_for @version do |f| %>
    <% for attribute in [:crop_x, :crop_y, :crop_w, :crop_h] %>
      <%= f.text_field attribute, :id => attribute, :value => 3 %>
    <% end %>
    <p><%= f.submit "Crop" %></p>
  <% end %>
</section>

</content:>

append-head:
<%= javascript_include_tag ‘jquery-1.3.2.min’ %>
<%= stylesheet_link_tag “jquery.Jcrop” %>
<%= javascript_include_tag “jquery.Jcrop.min” %>

$(function() {
$(’#cropbox’).Jcrop({
onChange: update_crop,
onSelect: update_crop,
setSelect: [0, 0, <%= @version.resolution.width %>, <%= @version.resolution.height %>],
aspectRatio: <%= @version.ratio %>
});
});

function update_crop(coords) {
  	var rx = <%= @version.resolution.width %> / coords.w;
    var ry = <%= @version.resolution.height %> / coords.h;
    $('#preview').css({
        width: Math.round(rx * <%= @version.foto.photo_geometry(:big).width %>) + 'px',
        height: Math.round(ry * <%= @version.foto.photo_geometry(:big).height %>) + 'px',
        marginLeft: '-' + Math.round(rx * coords.x) + 'px',
        marginTop: '-' + Math.round(ry * coords.y) + 'px'
    });
  var ratio = <%= @version.foto.photo_geometry(:original).width %> / <%= @version.foto.photo_geometry(:big).width %>;
  $("#crop_x").val(Math.round(coords.x * ratio));
  $("#crop_y").val(Math.round(coords.y * ratio));
  $("#crop_w").val(Math.round(coords.w * ratio));
  $("#crop_h").val(Math.round(coords.h * ratio));
}
</script>

</append-head:>
[/code]

Nie no porażka cały dzień w kibel i dalej zero kumacji co tu jest winne…

To chyba moje pierwsze rozczarowanie Railsami od 2 tygodni nauki :frowning:

[quote=mleszcz]Nie no porażka cały dzień w kibel i dalej zero kumacji co tu jest winne…

To chyba moje pierwsze rozczarowanie Railsami od 2 tygodni nauki :([/quote]
A ta linijka hobo_model, przy której jest komentarz, żeby nic na nią nie umieszczać? Nie znam hobo, ale może przerzuć ją na samą górę?

I druga sprawa: w którym miejscu określasz jakie powinny być te wielkości? Bo z kodu tego wyczytać nie mogę.

Jak atrybuty crop_* były pod hobo_model to się wysypywało w Version#update przy update_attributes.

Proszę:

[code=ruby]class Version < ActiveRecord::Base

belongs_to :resolution, :class_name => “VersionDefinition”

end

class VersionDefinition < ActiveRecord::Base

hobo_model # Don’t put anything above this

fields do
width :integer
height :integer
crop enum_string(:auto, :manual)
timestamps
end

def name
“#{width}x#{height} #{crop}”
end
end[/code]

No więc problem tkwi w dynamicznych stylach.
Tutaj sam Yurek o tym pisze.

Wracam zatem do wątku Paperclip - dynamiczna zmiana :styles gdzie opiszę jak to obejść.