I found no other way to change the path of “images” in a Rails application than monkey patching the AssetTagHelper like so:
module ActionView
module Helpers #:nodoc:
module AssetTagHelper
def image_path(source)
compute_public_path(source, 'static_images')
end
alias_method :path_to_image, :image_path # aliased to avoid conflicts with an image_path named route
end
end
end
Share This
The default behavior for quite a long time was :hard_breaks in the textilize helper method in rails.
Hard Breaks means: All line breaks are turned into <br />’s.
Somebody changed the textilize helper in “actionpack-2.3.4/lib/action_view/helpers/text_helper.rb” in 2.3.4 and added the ability to pass some options but broke the default behavior here:
def textilize(text, *options)
options ||= [:hard_breaks]
# ...
Options will never be null.
I fixed this by monkey patching the module through the following code in config/initializers/textilizepatch.rb
module ActionView
module Helpers
module TextHelper
def textilize(text, *options)
options = [:hard_breaks] if options == nil || options.size == 0
if text.blank?
""
else
textilized = RedCloth.new(text, options)
textilized.to_html
end
end
end
end
end
Such changes should be tested… *grml*
Share This
You can use
RAILS_DEFAULT_LOGGER.log "foobar"
# or
Rails.logger.log "blah"
outside a controller for logging.
Share This
The last Passenger update brought some good explanation off the problems regarding Passenger and memcache-client (see here).
Smart spawning of Passenger processes creates shared file descriptors. As the connections to memcached are sockets they are shared as well so data on them gets corrupted which is explained very nicely in the Passenger documentation: Example 1: Memcached connection sharing (harmful).
The solution presented there works like a charm. The reestablish_connection_to_memcached line is actually not more than CACHE.reset where CACHE is the reference to the memcache connection.
After that change, spawning methods smart-lv2 and smart will work in connection with environment.rb configured memcache connections.
Edit: As requested in the comments, a little example:
memcache_options = {
:c_threshold => 10000,
:compression => true,
:debug => false,
:namespace => 'some_ns',
:readonly => false,
:urlencode => false
}
CACHE = MemCache.new memcache_options
CACHE.servers = '127.0.0.1:11211'
begin
PhusionPassenger.on_event(:starting_worker_process) do |forked|
if forked
# We're in smart spawning mode, so...
# Close duplicated memcached connections - they will open themselves
CACHE.reset
end
end
# In case you're not running under Passenger (i.e. devmode with mongrel)
rescue NameError => error
end
In this case, CACHE is the global constant that i use to access my memcache-client.
I guess you’ll need to do the same with the global Rails.cache object, but i’m not sure. Anyway, the above solution works for me.
Share This
I recently switch from a mod_proxy / thin setup to Phusion Passenger and my application started to do the funniest things and the production.log was full with errors related to memcached.
It seems, that passengers spawn method “smart” isn’t compatible with memcached. Within seconds on a lightly loaded server the cache gets corrupted big time.
I got better results with a newer memcache client (the ruby gem actually), but for that i need to remove the client from the rails vendor lib. Furthermore, under higher load there still where errors.
Only solution is to set the spawn method to conservative like so
RailsSpawnMethod conservative
Problem seems to be known in the Phusion and Rails teams.
Share This
Ruby on Rails I18n infrastructure did a great job to internationalization in Rails applications. Most things work right out of the box.
Daily Fratze is fully internationalized and i wanted to use ordinal day numbers in the English version. Pity, there is no template for strftime that works that way.
As i already hat monkey patched a “t” method to all date and time related classes, i came up with the following solution:
Parallel to “en.yml” i now have “en.rb” in my locales folder which gets loaded in environment.rb via
config.i18n.load_path += Dir[File.join(RAILS_ROOT, 'app', 'locales', '*.{yml,rb}')]
The en.rb files defines some procs as translation values like so:
{
:'en' => {
:date => {
:formats => {
:dmy_with_long_month => lambda { |date| "%B #{date.day.ordinalize}, %Y" },
}
},
:time => {
:formats => {
:dmy_with_long_month => lambda { |date| "%B #{date.day.ordinalize}, %Y" },
:dmy_with_full_day_and_long_month_and_time => lambda { |date| "%A, %B #{date.day.ordinalize}, %Y at %H:%M" }
}
}
}
}
Used with the standard I18n tools you’ll end up with the string representation of the proc object. Useless
So time for monkeypatching like so:
module DateTimeSupport
def t(format = nil)
type = self.respond_to?(:sec) ? 'time' : 'date'
formats = I18n.translate(:"#{type}.formats")
format = formats[format.to_sym] if formats && formats[format.to_sym]
I18n.localize(self, :format => format.respond_to?(:call) ? format.call(self) : format)
end
end
class Time
include DateTimeSupport
end
class Date
include DateTimeSupport
end
class DateTime
include DateTimeSupport
end
class ActiveSupport::TimeWithZone
include DateTimeSupport
end
Code resides in a file in config/initializers and gets loaded automatically. It adds a t method to all date and time related classes. The method tries to look up the translation of format just like I18n/Simple does.
If it is proc, it gets called and then passed to I18n, otherwise it the original parameter is used.
That way the t method can use “dmy_with_long_month”, :dmy_with_long_month and any other arbitrary format like “%B %Y” that is not defined in any language file.
Share This
Again, the MySQL ruby gem totally annyoed me trying to install it on a fresh Mac OS X 10.5.5 install and MySQL 5.0.67.
This time the following command brought it to life:
sudo env ARCHFLAGS="-arch i386" gem install mysql -- \
--with-mysql-dir=/usr/local/mysql --with-mysql-lib=/usr/local/mysql/lib \
--with-mysql-include=/usr/local/mysql/include
Thanks to a bitter software engineer.
Share This
If you followed the instructions here and used the method named PDF::Writer (Austin Ziegler), you we’re out of luck when Rails 2.1 appeared.
With Rails 2.2.2 once again the rendering mechanism seems to have changed big time and my previous post on how to make the pdf/writer gem work with a custom template handler doesn’t work anymore.
With the help of Josh Peek i was able to fix this. He gave me the following code to enable a rpdf template handler with pdf-writer:
module ActionView # :nodoc:
require 'pdf/writer'
class PDFRender < ActionView::TemplateHandler
PAPER = 'A4'
include ApplicationHelper
include ActionView::Helpers::TranslationHelper
include ActionView::Helpers::AssetTagHelper
include ActionView::Helpers::TextHelper
include ActionView::Helpers::TagHelper
include ActionView::Helpers::UrlHelper
def self.call(template)
"ActionView::PDFRender.new(self).render(template, local_assigns)"
end
def initialize(action_view)
@action_view = action_view
end
# Render the PDF
def render(template, local_assigns = {})
@action_view.controller.headers["Content-Type"] ||= 'application/pdf'
# Retrieve controller variables
@action_view.controller.instance_variables.each do |v|
instance_variable_set(v,
@action_view.controller.instance_variable_get(v))
end
pdf = ::PDF::Writer.new( :paper => PAPER )
pdf.compressed = true if RAILS_ENV != 'development'
eval template.source, nil, ''
pdf.render
end
end
end
ActionView::Template.register_template_handler 'rpdf', ActionView::PDFRender
Just drop this under config/initializers and you’re fine.
Share This
I couldn’t find this in the documents, but Geoff Buesing showed me the hooks to turn off Ruby On Rails’ automatic timezone conversions for some columns of a model or a complete model:
# Turn it off for just some columns
class Picture < ActiveRecord::Base
def self.skip_time_zone_conversion_for_attributes
[:created_at, :published_at]
end
end
# Turin it off for the whole model
class Picture < ActiveRecord::Base
def self.time_zone_aware_attributes
false
end
end
Thanks a lot!
Share This
The “x_sendfile” argument on the send_file method in Rails 2.1 is not well thought off as it has an impact in development mode also. I guess most Rails coders won’t have Apache proxying their mongrels in dev mode and so they don’t get to see any images or files but the plain path information.
I’ll guess i stay with the x_send_file solution as described here.
Share This