I pushed an update to the Mailbuild gem this morning in response to a bug report from Michael Larocque, who found it wasn’t properly defaulting to the first List ID if none was specified explicitly.
Full details can be found in the commit on the github mirror.
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'
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 %>
I’ve pushed a small update to the Mailbuild gem this morning which adds support for multiple subscriber lists, enabling you to manage different types of subscribers from within your application.
The sample Rails application has also been updated to take into account the slightly changed syntax for specifying your list id(s);
Mailbuild.list_id = 'LIST_ID_HERE'
…is now…
Mailbuild.list_ids = {:newsletter = 'LIST_ID_HERE'}
All API calls take a list id as their last parameter, which defaults to the first id you declare in the list_ids hash.
You can use a specific subscriber list id as follows;
Mailbuild.add(params[:email], params[:name], Mailbuild.list_ids[:newsletter])
The documentation explains what parameters each method accepts.
For anyone working on a Rails application which deals with countries or languages, the official source of data is the International Standards Association, specifically ISO 3166 for countries and ISO 639 for languages.
To make it easier to get this data into your Rails application, I’ve created two generators which automatically create the models, migrations and data you’ll need and bundled them up in a handy Rails plug-in.
Usage couldn’t be simpler…
script/plugin install git://github.com/cameronyule/isodata.git
If you want country data…
script/generate countries
rake db:migrate
rake isodata:db:countries
…and for languages…
script/generate languages
rake db:migrate
rake isodata:db:languages
Check out the isodata project on Github.