I’ve finally committed my Rails 2.1 YUI Uploader example, which is a fully-functioning Rails 2.1.2 application demonstrating the use of YUI Uploader, attachment_fu, CSRF protection and the Restful Authentication plugin. It’s using the latest 2.6.0 release of YUI, which includes the fixes to the the Uploader for Flash Player 10.
It’s up on Github now, all the details you’ll need are in the README.
I’ve updated the Rails 2.1 SWFUpload example to use the new 2.2.0 Beta 2 release of SWFUpload. The reason for the new release is that there were security changes in Flash Player 10 which prevent JavaScript from causing Flash to show a file dialog – the browse button is now rendered by Flash itself.
I’ve been having an issue with Has Many Polymorphs tagging functionality where I was getting a "Model is not a taggable model" error while using the tagging methods.
As I’m not alone in having this problem, here’s a quick fix.
At the bottom of environment.rb;
require 'tagging_extensions'
require 'tag'
It’s easy to forget that Rails isn’t limited to the default development, test and production environments and I’ve found a custom staging environment comes in useful.
A staging environment is identical to production in terms of caching and performance, but allows you to target configuration settings for testing on your live server.
The common use case for me has been commerce applications where you can use the staging environment to automatically switch to your payment provider testing account while everything else is as per production.
Here’s how you can get a staging environment up and running.
- Copy production.rb to staging.rb in config/environments
- Add a staging entry to your config/database.yml
- Assuming your staging DB exists, that’s it!
You can then test it out with mongrel
ruby script/server -e staging
or alternatively if you use Phusion Passenger (mod_rails)
<VirtualHost XX.XX.XX.XX:80>
…
RailsEnv staging
</VirtualHost>
As part of a CMS I’m building I wanted the ability to audit user interaction with data, to prevent the situation where content is being created, deleted or edited with no record of who did what and when.
John Nunemaker recently released his User Stamp plug-in which stamps records with the ID of the users that created and last updated. The implementation is quite clever, as he’s managed to work around the usual hack of storing the current user ID in Thread.current to make it accessible to the model by using a Sweeper, as they have access to controllers (and hence the current_user method).
I’ve taken his code a bit further by creating a Log model which stores a polymorphic reference to the record affected, the event that occurred (e.g. ‘deleted’ or ‘updated’), the current user ID and the time it happened.
The Log model;
class Log < ActiveRecord::Base
# Relationships
belongs_to :user
belongs_to :loggable, :polymorphic => :true
# Validations
validates_presence_of :loggable_type
validates_presence_of :loggable_id
validates_presence_of :action
validates_presence_of :user
end
The migration;
class CreateLogs < ActiveRecord::Migration
def self.up
create_table :logs do |t|
t.string :loggable_type
t.integer :loggable_id
t.string :action
t.references :user
t.timestamps
end
add_index :logs, :loggable_id
add_index :logs, :user_id
end
def self.down
drop_table :logs
end
end
Additional callback methods added to UserStampSweeper;
def after_create(record)
add_log(record, 'created')
end
def after_update(record)
add_log(record, 'updated')
end
def after_destroy(record)
add_log(record, 'delete')
end
private
def add_log(record, action)
Log.create(
:loggable_type => record.class.to_s,
:loggable_id => record.id,
:action => action,
:user => current_user
)
end
Displaying the logs;
<% for log in @logs %>
<tr>
<td><%= link_to (h log.loggable.log_name), [:admin, log.loggable] %></td>
<td><%= h log.loggable_type %></td>
<td><%= h log.action %></td>
<td><%= link_to (h log.user.display_name), [:admin, log.user] %></td>
<td><%= log.created_at.to_s %></td>
</tr>
<% end %>