Attachment_fu or Paperclip for Rails3 - paperclip

I have just upgraded to rails3 and when I installed my usual attachment_fu plugin failed. So I started googling it and although I did manage to find a rails3 version there seemed to be a lot more people talking about paperclip with rails3.
So firstly what are the advantages of paperclip?
Is there better support for rails3 with it?

Neither. Use carrierwave .
To handle the file uploads, I’ve switched from Paperclip to CarrierWave. While Paperclip has (and continues) to serve me well in many applications I work with, I really appreciate the modular approach that CarrierWave takes. It’s agnostic as to which of the popular S3 clients you use, supporting both aws/s3 and right_aws. It’s also ORM agnostic and not tightly coupled to Active Record. The tight coupling of Paperclip has caused us some grief at work, and I’m also confused about the state of Paperclip’s support for aws/s3 and right_aws. So, I was happy to find this new project, and the maintainer Jonas Nicklas seems to be an extremely responsive and helpful dude, which is always good thing. The code looks great, and I’ve had an easy time working with this library so far. (from: http://trevorturk.com/2010/2/8/kzak-an-open-source-web-based-jukebox/)
More info here:
http://techblog.moviepilot.com/carrierwave-as-a-replacement-for-paperclip

I made attachment_fu rails3 compatible.
See https://github.com/mihael/attachment_fu
EDIT: but it is broken for some users, and i am not maintaining it further, so please look into other solutions, if you do not want to hack it yourself ;)
I tested paperclip vs carrierwave vs attachment_fu with rails3.0.3 for a project I am working on.
So far attachment_fu works very well as always, but the code still needs some refactoring with the callback system. It has backends for cloudfiles, s3.
Paperclip is also very good and is very easy to use. The basic setup did not let me upload movies (had to add option :whiny=>false), and it did not sanitize filenames the way I expected. This is how I did it:
class Asset < ActiveRecord::Base
has_attached_file :file, :styles => { :small => "300x300>", :thumb => "50x50>" }, :whiny => false
before_create :sanitize_file_name
private
def sanitize_file_name
self.file.instance_write( :file_name, file_file_name.gsub(/[^A-Za-z0-9\.\-]/, '_'))
end
end
Paperclip has s3 backend, but does not have a backend for cloudfiles built-in. There is a paperclip fork for that (google for paperclip-cloudfiles) which is built for rails2.3.5 (search github for paperclip_demo).
Carrierwave looks very nice, with the decoupled architecture, but I do not like the fact that it does not delete stuff on updates and destroys of objects, leaving a bunch of files and directories on disk. The basic carrierwave setup also did not let me upload movies, although it sanitizes filenames nicely. I did not found a quick fix for this, yet. If You are using Mongoid and GridFS, carrierwave has built in support.
Finally, I took Paperclip for my project.

I've created a gem for attachment_fu if you want to continue using it in Rails 3.2 and beyond.
https://rubygems.org/gems/pothoven-attachment_fu

Dragonfly is really good. Try it out, it can handle files and images.

Related

Is there a template for a website that accepts an uploaded file, does something, and lets the user download the result?

I have a few Ruby scripts that process text files in different ways, that many of my friends find useful. However, most of the people I know are not comfortable running scripts on the command line. The easiest thing for them would be to create a simple webpage where people could upload a file, select a few options, have it processed, and then download the result.
I know it wouldn't be too hard to build something like this in Rails or Merb or something like that, however it seems like a very common problem, so I was wondering if there was already some kind of template, or similar application that I could easily modify, i.e. let the user upload a file, choose a few options, then {fill in code to do something with file}, let the user download the resulting file?
In the past I used Carrierwave to upload user avatars.
If you are used to Rails it's really straightforward.
Let it be a TextFile resource:
gem 'carrierwave'
$ rails g scaffold textfile content:string title:string etc etc
$ rails g uploader textfile
class TextFile < ActiveRecord::Base
attr_accesible :content
mount_uploader :content, TextFileUploader
end
And that is is pretty much all you have to do to obtain the app's skeleton. However, to answer your real question, no, I don't think there is already a rails app that does exactly that.
https://github.com/jnicklas/carrierwave
I found sinatra-fileupload, which pretty perfectly answers my question. It's a very minimalistic framework which works perfectly, I can just plug in the file handling, and change the layout etc a bit. There were many examples of sophisticated Rails plugins linked to databases, with versioning and stuff, but I really wanted the most minimal example.

Ruby on Rails with chargify

I want to integrate chargify to my rails app. I have user object and I want the user to be able to subscribe for one month and update the boolean column on user object. I prefer to use the API not hosted pages. How can I do that?
Is there any example for chargify on ruby on rails for handling subscriptions but with details about mvc for newbies?
Based on this thread and the Googles it looks like there is not a whole lot out there.
You could try looking at the Rails 2 example here and converting it or use the gem here (gem "chargify", "~> 0.3.0").
I know none of this is aimed at newbies but the info seems to sparse.
This might get you going. It seems that Chartify itself is written in Rails, and therfore their API is ruby code, which you can use...

Rails HTTP streaming with HAML

There appears to be an issue with using HTTP streaming with HAML projects in rails. It works perfectly if I use ERB instead. Apparently, I'm not the only one with this problem.
It doesn't work with placing stream at the top of the controller, or with using render :stream => true in the action.
How can I get HAML and HTTP streaming to play nicely together?
Update: I've opened an issue on the gem's page, here.
This is not yet supported by HAML (source):
HTTP streaming is the sort of thing that would require a substantial
set of modifications to the core Haml engine. It's only moderately
tricky to get it working even in basic cases, but when you factor in
things like the whitespace-eating operators it gets much more
difficult.
This isn't something I'm opposed to in theory, but it's also not
something that's high on my priority list given the difficulty of
implementing it.
The internals of Haml are such that it is indeed writing out to a buffer as it goes along. However, the "standard" API that Rails has traditionally provided for templating languages is a fairly straightforward in-and-out call. I don't think Haml does currently have "streaming support", but its simply more of an API issue than anything else.
I'm curious as to how Rails is plugging into ERB to do this.

Controlling Rails Initialization for an app extracted as an engine

I was hoping to make a Rails app usable both as an Engine and as a standalone Application.
Specifically, I have a nascent app which I'd like to plug in to a customer's site, but ideally, I'd like to just as easily use the app as a standalone system. However, if config/environments/*.rb exist in the enginified version of my app, I get an Uninitialized Constant error at the time the app that I'm having take a dependency on my engine starts up; Rails complains that the MyEngineModule::Application constant can't be found in development.rb, which I think is simply a load order issue, since this does NOT occur when I run the app standalone. If I delete development.rb, the original initializers that reference my MyEngineModule::Application complain, so then I tried to delete those, and all is well.
Great, except that the original app doesn't work, since its configuration is gone.
Is there some tweak I can make to the initialization load order (or load paths, in the Engine < Rails::Engine class definition) that would prevent the original configs and initializers from being loaded when in an engine context, and allow me to leave them in place for the app context?
The simpler answer is probably this, but I'm feeling stubborn, and would like to know what it would take to make my original goal possible:
extract the code for MyEngine into an engine, remove the config/environments/* files and config/initializers/* files, and make the client app depend on this.
Make a "new" minimalist app depend on MyEngine, and move the environment files and initializers to NewApp.
Assuming I feel some unnatural compulsion to keep my original application runnable as it was, if I want to prevent the "engine" from loading the "application" configuration, what's the best way to handle that? I presume this is only really a problem during development, because I can prevent the environments/*.rb files from being pulled into the gem itself, but I like being able to test locally while I'm developing the engine and its client app.
Continuing my tradition of answering my own esoteric questions, it seems like one passable alternative is to include a guard clause in the engine's environments/*.rb and the initializers that goes something like this:
if defined? CuteEngine::Application
CuteEngine::Application.configure do
config.whatever = something
end
end
This gets around the problem of having two Rails::Application objects at a relatively small cost. Not very happy about it, but I'll live.
Bumping this for new comers.
Rails 3.1 comes with mountable engines, which sounds like exactly what you are describing. The docs aren't great for converting existing code, but it looks like this will do what you want:
module CuteEngine
class Engine < ::Rails::Engine
isolate_namespace CuteEngine
end
end
In your other app's routes.rb file, you'll add:
mount CuteEngine::Engine, at: "/cuteness"
http://edgeguides.rubyonrails.org/engines.html#mounting-the-engine
http://railscasts.com/episodes/277-mountable-engines

A copy of ApplicationController has been removed from the module tree but is still active

Whenever two concurrent HTTP requests go to my Rails app, the second always returns the following error:
A copy of ApplicationController has been removed from the module tree but is still active!
From there it gives an unhelpful stack trace to the effect of "we went through the standard server stuff, ran your first before_filter on ApplicationController (and I checked; it's just whichever filter runs first)", then offers the following:
/home/matchu/rails/torch/vendor/rails/activesupport/lib/active_support/dependencies.rb:414:in
`load_missing_constant'
/home/matchu/rails/torch/vendor/rails/activesupport/lib/active_support/dependencies.rb:96:in
`const_missing'
which I'm assuming is a generic response and doesn't really say much.
Google seems to tell me that people developing Rails Engines will encounter this, but I don't do that. All I've done is upgrade my Rails app from 2.2 (2.1?) to 2.3.
What are some possible causes for this error, and how can I go about tracking down what's really going on? I know this question is vague, so would any other information be helpful?
More importantly: I tried doing a test run in a "production" environment just now, and the error doesn't seem to persist. Does this only affect development, then, and need I not worry too much?
This is a bug in Rails 2.3.3:
https://rails.lighthouseapp.com/projects/8994/tickets/2948-exception-a-copy-of-actorscontroller-has-been-removed-from-the-module-tree-but-is-still-active
There is a patch for it (but incomplete?) in 2-3-stable:
http://github.com/rails/rails/commit/d37ac7958fc88fdbf37a8948102f6b4e45c530b3
You have a few options to address the problem:
Revert to Rails 2.3.2, wait for 2.3.4 to come out, probably at the end of August. 2.3.3 has a couple bad issues, so that might be best.
The problem should not happen in production mode, nor will it happen in development mode under the Thin server. If you are having this issue on Google Engines in production mode, the patch is your only hope. If it's only in dev mode, you can just run your local server with Thin instead of Mongrel.
If it is Google Engines, you can move off of Google Engines and host your app another way. This seems like a lot of work though.
Best of luck, this is a really bad bug many people are running into.
I addition to the workarounds mentioned in the other answers, I have encountered two others:
Add "config.cache_classes = false" to your config/environments/development.rb file. This has the unfortunate side effect of requiring you to restart your server whenever you want to see your changes.
Add 'unloadable' inside your controller classes in your engine. See http://strd6.com/?p=250 and http://dev.rubyonrails.org/ticket/6001
I haven't tried the second approach, since I found the other solution first, but there is of course a trade-off between avoiding having to edit plugin code, which may be reverted if a newer version of the plugin is downloaded, and then the ease of development provided by not having to restart the development server all the time in the second solution.
i faced with same problem for my new engine on rails 2.3.4 and i found solution here.
calling unloadable method solved my problem.
Weird.
Trying running "rake rails:update" to make sure the configs are scripts are up to date. You may have to check the existing ones against a template application.
i had this error and from memory it was one of one of these three things that fixed it.
1) I needed to update mongrel/rack
2) I had an environment variable from restful authentication that i had moved into the production.rb and development.rb files from the environment.rb - shifting it back to environment.rb seemed to help
3) will_paginate was out of date
We called out to an activerecord model in a namespaced module which overrides the "name" class method. Rails expects that the name method returns Product::Categories::MilkProducts::Firstproduct but gets just Firstproduct and throws an error. So if you get this error first check if you redefined self.name.
Firstproduct.method(:name).owner should be Module
Firstproduct.method(:name).source_location
source:
module Product::Categories::MilkProducts
class Base
def self.name
self.to_s.demodulize
end
end
class Firstproduct < Base
self.product = Product.first
end
end

Resources