MacPorts is a fantastic resource for installing and managing libraries on OSX. When working with Ruby on Rails, I installed MySQL (and Postgresql) using MacPorts, but had trouble getting the MySQL gem to install and connect. The error message I received was:
Here is the magic formula:
sudo gem install -v 2.7 --no-rdoc --no-ri mysql --
--with-mysql-dir=/opt/local/lib/mysql5
--with-mysql-config=/opt/local/lib/mysql5/bin/mysql_config;
I am making the transition from attachment_fu to paperclip on a very large project of mine. I wrote the following method, inside of my old attachment_fu model ItemImage to do the work. I wrote it to run from inside the rails console. It gives handy messages out letting you know what happened.
Calendar Date Select is a new(ish) “date and time picker”, developed by Tim Harper, designed primarily for developers to use in Rails applications. It uses the standard Prototype JavaScript library, and is easily installed as a Rails plugin:
On the surface this is a very easy plugin to install and use. It seems the common problem is that there is very little documentation available and the demo server is down. After installing the gem, I was able to run “gem server” and view the rdoc for the plugin. A couple of things I thought would be helpful to repost here:
Form Helpers:
calendar_date_select(object, method, options={})
Similar to the difference between text_field_tag and text_field, this method behaves like text_field
It receives the same options as calendar_date_select_tag. Need for time selection is automatically detected by checking the corresponding column meta information of Model#columns_hash
calendar_date_select_tag( name, value = nil, options = {})
Similar to text_field_tag, but adds a calendar picker, naturally.
Arguments
+name+ - the html name of the tag
+value+ - When specified as a string, uses value verbatim. When Date, DateTime, Time, it converts it to a string basd off the format set by CalendarDateSelect#format=
+options+ - ...
Options
:embedded
Put the calendar straight into the form, rather than using a popup type of form.
<%= calendar_date_select_tag "name", "2007-01-01", :embedded => true %>
:hidden
Use a hidden element instead of a text box for a pop up calendar. Not compatible with :embedded => true. You‘ll probably want to use an onchange callback to do something with the value.
<%= calendar_date_select_tag "hidden_date_selector", "", :hidden => "true", :onchange => "$('cds_value').update($F(this));" %>
:image
Specify an alternative icon to use for the date picker.
To use /images/groovy.png:
<%= calendar_date_select_tag "altered_image", "", :image => "groovy.png" %>
:minute_interval
Specifies the minute interval used in the hour/minute selector. Default is 5.
<%= calendar_date_select_tag "month_year_selector_label", "", :minute_interval => 15 %>
:month_year
Customize the month and year selectors at the top of the control.
Valid values:
* "dropdowns" (default) - Use a separate dropdown control for both the month and year
* "label" - Use static text to show the month and the year.
<%= calendar_date_select_tag "month_year_selector_label", "", :month_year => "label" %>
:popup => ‘force‘
Forces the user to use the popup calendar by making it‘s text-box read-only and causing calendar_date_select to override it‘s default behavior of not allowing selection of a date on a target element that is read-only.
<%= calendar_date_select_tag "name", "2007-01-01", :popup => "force" %>
:time
Show time in the controls. There‘s three options:
* +true+ - show an hour/minute selector.
* +false+ - don't show an hour/minute selector.
* +"mixed"+ - Show an hour/minute selector, but include a "all day" option - allowing them to choose whether or not to specify a time.
:year_range
Limit the year range. You can pass in an array or range of ruby Date/Time objects or FixNum‘s.
<%= calendar_date_select_tag "e_date", nil, :year_range => 10.years.ago..0.years.from_now %>
<%= calendar_date_select_tag "e_date", nil, :year_range => [0.years.ago, 10.years.from_now] %>
<%= calendar_date_select_tag "e_date", nil, :year_range => 2000..2007 %>
<%= calendar_date_select_tag "e_date", nil, :year_range => [2000, 2007] %>
CALLBACKS
The following callbacks are available:
* before_show / after_show
* before_close / after_close
* after_navigate - Called when navigating to a different month. Passes first parameter as a date object refering to the current month viewed
* onchange - Called when the form input value changes
<%= calendar_date_select_tag "event_demo", "",
:before_show => "log('Calendar Showing');" ,
:after_show => "log('Calendar Shown');" ,
:before_close => "log('Calendar closing');" ,
:after_close => "log('Calendar closed');",
:after_navigate => "log('Current month is ' + (param.getMonth()+1) + '/' + (param.getFullYear()));",
:onchange => "log('value changed to - ' + $F(this));"
}}}
All callbacks are executed within the context of the target input element. If you‘d like to access the CalendarDateSelect object itself, you can access it via "this.calendar_date_select".
For example:
<%= calendar_date_select_tag "event_demo", "", :after_navigate => "alert('The current selected month is ' + this.calendar_date_select.selected_date.getMonth());" ,
For use with Form Builders
calendar_date_select(method, options = {})
Controllers:
In my application, I am using a custom form builder, so I used the calendar_date_elect with the form builder. The options hash appears to be the same as in the other view tags, so I just passed along what I needed:
I was pleased to discover that, utilizing some of the magic of Rails, the date property on my event was automatically turned into a datetime attribute, and on editing, was reloaded into the calendar as expected.
I need a way to call a process on a regular basis inside of my Rails application. I have been working in and around this idea for over a year and have tried several different methods.
One thing to mention is that CRON jobs are an obvious solution to these problems. However, as I am serving off a Joyent server, I have had difficulty setting up my CRON jobs and getting them into the right file with the right RAILS_ROOT settings to my application files. If anyone knows a good way to set these up on Joyent, please let me know!
config/initializers/task_scheduler.rb:6: undefined method `start_new' for Rufus::Scheduler:Module (NoMethodError)
This was caused because I didn’t include the rufus/scheduler line at the top of my config/initializers/task_scheduler.rb file:
require 'rufus/scheduler'
I only include this oversight in case someone else happens to encounter the same error in their code.
Back To BackgrounDRb
Rufus Scheduler worked great for the simple tasks, but some of what I am trying to do has the potential to take up a lot of time. The problem I encountered with rufus was that as the time requirements grew, it was taking more and more instances from my mongrel cluster, eventually drawing the server request/response cycle to a complete stop. Not good when you are trying to host a public site!
Because I know that these processes can be time consuming, they need to be relegated to a separate server instance. So I am returning to BackgrounDRb.
My previous experiences with BackgrounDRb produced the following opinion from my own blog post:
I really like the theory and concept behind BackgrounDRb, but it seems to be a bit overkill for what I am trying to accomplish. Also, it was almost impossible to keep the BackgrounDRb server running, even with the use of Monit. There just always seemed to be something that was crashing our beloved process.
Learning from my previous experiences, I have thoroughly tested and retested the code that will be called from my workers. I am setting things up to run using the add_periodic_timer method as my first attempt. On my local machine, everything seems to be working fantastically. I plan to set everything in motion on my production server tonight and see where we sit in the morning.
The First Results
I am happy to report that with the proper configuration, and the strategic placement of begin .. rescue Exception code, BackgrounDRb is successfully performing the functions I require!
One comment that I have is that it is difficult to figure out what it is doing when. To counter this issue, I have designed a very simple background_logger to monitor the processes and let me know when things start and stop.
To do this, you first make a class for the BackgroundLogger:
From lib/background_logger.rb:
class BackgroundLogger < Logger
def format_message(severity, timestamp, progname, msg)
"#{timestamp.to_formatted_s(:db)} #{severity} #{msg}\n"
end
end
Then you add awareness of this logger in your environment file:
This adds a contstant called BACKGROUND_LOG that you can then use in your workers:
From lib/workers/foo_worker.rb:
class FooWorker < BackgrounDRb::MetaWorker
set_worker_name :foo_worker
def create(args = nil)
BACKGROUND_LOG.info("Foo Worker Started")
add_periodic_timer(5400) { do_foo }
end
def do_foo
BACKGROUND_LOG.info("Starting Foo...")
MyModel::do_foo
BACKGROUND_LOG.info("Foo Done!")
end
end
The resulting log output will include timestamps and such that can help you keep track of what is going on, when it happens, and in the event of a hiccup, let you know when it happened and in which file. This is of course in addition to the information provided in BackgrounDRb’s own logs.
So, BackgrounDRb is NOT the answer… what else is there?
Everything was peachy until my processes gre to be very large in number. Not good when it takes so long to do something that the machine chokes and it all grinds to a halt!
So what are my other options? Turns out that now everyone recommends delayed_job, a plugin from shopify that does the same thing only better. The folks at Engine Yard highly recommend delayed_job over backgrounDRb due to severe memory leaks and other not so favorable conditions.
I am happy to report that the results are excellent! Without even having Monit or God running, delayed_job has been kicking serious butt on my project. I think I’ll stick with it for awhile.
Monitoring All Of These Processes
The next part is to explore how to keep it all running when I run off to play music for the weekend. I know that Monit is a common choice, and having read up about it, it might be the best option. I am however, going to start with a different option… you can follow my progress in this area from my Daemon Monitoring blog post.
The FeedNormalizer Gem does an excellent job of returning a single unified object from many of several different syndicated feed types. This saves you from having to worry about whether you are dealing with an rss, atom or some other kind of feed.
The following is a list of the available fields for both the Feed object itself and the Entries objects associated as articles in the channel.
FeedNormalizer::Feed
title
description
id
last_updated
copyright
authors / author
urls / url
image
generator
items / channel
FeedNormalizer::Entry
content
description
title
date_published
urls / url
id
authors / author
copyright
categories
Etags
Etags and last_modified are crucial elements to sending proper request headers if you hope to receive conditional get responses and save yourself some overhead in feed processing. FeedNormalizer does not provide access to these elements as they are actually part of the http response headers, and not the feed itself.
While heavily studying the art of feed processing, I encountered Feezirra and Feedtosis, both excellent libraries for feed processing. My own application required a modified version of their concept, but there was a lot to learn in their code.
Feedtosis uses the HttpHeaders process to collect this information from a Curl::Easy object. I adapted the Feedtosis code to meet my needs like this:
require 'http_headers'
class Feed < ActiveRecord::Base
def store_header_information
headers = HttpHeaders.new(curl.header_str)
self.response_code = curl.response_code
self.etag = headers.etag unless headers.etag.nil?
self.last_modified = headers.last_modified unless headers.last_modified.nil?
end
end