Never been to DZone Snippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

About this user

Duane Johnson http://blog.inquirylabs.com/

« Newer Snippets
Older Snippets »
Showing 1-10 of 10 total  RSS 

ActiveRecord::Errors#to_xml

Here’s a method that will allow you to call to_xml on an ActiveRecord::Errors object. We’re using this to pass errors between web apps via a web service api.

class ActiveRecord::Errors
  def to_xml(options = {})
    options[:indent] ||= 2
    options.reverse_merge!({ :builder =>
      Builder::XmlMarkup.new(:indent =>
        options[:indent]), :root => "errors" })
    options[:builder].instruct! unless options.delete(:skip_instruct)

    options[:builder].__send__(options[:root].to_s.dasherize) do |xml|
      @errors.each do |key, value|
        xml.__send__(key.to_s.dasherize) do |xm|
          for message in value
            xm.message(message)
          end
        end
      end
    end

  end
end

Validate URIs by Pinging the Server

require 'open-uri'

class ActiveRecord::Base
  def self.validates_uri_existence_of(*attr_names)
    configuration = { :message => "is not a valid web address" }
    configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
    validates_each attr_names do |m, a, v|
      begin
        # Try to open the URI
        open v
      rescue
        # Report the error if it throws an exception
        m.errors.add(a, configuration[:message])
      end
    end
  end
end


Details on my blog.

Use background color to show error fields instead of wrapping them in a div

Using the default rails field_error_proc may lead to some layout headaches--your form looks perfect until, uh-oh, someone entered an invalid email address and Rails adds a fieldWithError-styled div that wraps around the problem field.

While this works in many cases, some pixel-perfect layouts may not be able to tolerate the 2-pixel padding around the text_field caused by the red border. An alternative is to change the background color of the offending field.

Include the following code in environment.rb (or use a "require" like I do):

ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
  error_style = "background-color: #ffff80"
  if html_tag =~ /<(input|textarea|select)[^>]+style=/
    style_attribute = html_tag =~ /style=['"]/
    html_tag.insert(style_attribute + 7, "#{error_style}; ")
  elsif html_tag =~ /<(input|textarea|select)/
    first_whitespace = html_tag =~ /\s/
    html_tag[first_whitespace] = " style='#{error_style}' "
  end
  html_tag
end


See my blog.inquirylabs.com for more Rails stuff.

content_tag that accepts a block = block_tag

Sometimes I want to do something like this:

<% content_tag("div", :class => "section_with_error" do %>
  HTML GOES HERE
<% end %>


instead of this:

<%= content_tag("div", "HTML GOES HERE", :class => "section_with_error") %>


Put the following code in ApplicationHelper, and you can do just that (replacing "content_tag" in the example above with "block_tag", of course):

  def block_tag(tag, options = {}, &block)
    concat(content_tag(tag, capture(&block), options), block.binding)
  end

Parse Technorati-style Tags from HTML

An enhancement to the String class that parses out Technorati-style tags. Uses Typo's strip_html method to remove img tags and other markup.

class String
  # Strips any html markup from a string
  TYPO_TAG_KEY = TYPO_ATTRIBUTE_KEY = /[\w:_-]+/
  TYPO_ATTRIBUTE_VALUE = /(?:[A-Za-z0-9]+|(?:'[^']*?'|"[^"]*?"))/
  TYPO_ATTRIBUTE = /(?:#{TYPO_ATTRIBUTE_KEY}(?:\s*=\s*#{TYPO_ATTRIBUTE_VALUE})?)/
  TYPO_ATTRIBUTES = /(?:#{TYPO_ATTRIBUTE}(?:\s+#{TYPO_ATTRIBUTE})*)/
  TAG = %r{<[!/?\[]?(?:#{TYPO_TAG_KEY}|--)(?:\s+#{TYPO_ATTRIBUTES})?\s*(?:[!/?\]]+|--)?>}
  def strip_html
    self.gsub(TAG, '').gsub(/\s+/, ' ').strip
  end

  def tags
    scan(/<a\s+[^>]*\s*rel=\s*(.?)tag\1[^>]*>(.+?)<\/a>/i).
    map { |match| match.last.strip_html rescue nil }.
    compact.select { |s| !s.strip.empty? }
  end
end

# Example usage

s = %{<a href="http://www.docstrangelove.com/tag/civil-war" rel="tag">civil war</a> <a href="http://www.technorati.com/tag/civil+war" rel="tag"><img src="http://www.docstrangelove.com/wp-content/plugins/UltimateTagWarrior/technoratiicon.jpg" alt="Technorati tag page for civil war"/></a> <a href="http://www.docstrangelovecom/tag/iraq" rel="tag">iraq</a> <a href="http://www.technorati.com/tag/iraq" rel="tag"><img src="http://www.docstrangelove.com/wp-content/plugins/UltimateTagWarrior/technoratiicon.jpg" alt="Technorati tag page for iraq"/></a>}

s.tags
# => ["civil war", "iraq"]

Firing a controller's action from the console

It seems like a simple task, but here's how you can simulate the calling of a controller's action:

ruby script/console

irb> require 'action_controller/test_process'
irb> require 'application'
irb> require 'site_controller'
irb> request = ActionController::TestRequest.new
irb> response = ActionController::TestResponse.new
irb> request.env['REQUEST_METHOD'] = 'GET'
irb> request.action = "late_employee"
irb> InfoController.process(request,response)


Basically, it's like getting inside of a TestUnit method, but you have to do the dirty work yourself.

Make an html link update several dom elements at the same time.

    <a href="#" onClick="<%= remote_function(:update => 'fashion1', :url => { :action => :get_fashion_for_color, :color_name => color_name, :number => 1 })%>;
                         <%= remote_function(:update => 'fashion2', :url => { :action => :get_fashion_for_color, :color_name => color_name, :number => 2 })%>;
                         <%= remote_function(:update => 'fashion3', :url => { :action => :get_fashion_for_color, :color_name => color_name, :number => 3 })%>;
                         return false;">

Autoinclude CSS Files by Controller/Action Name

def stylesheet_auto_link_tags
  stylesheets_path = "#{RAILS_ROOT}/public/stylesheets/"
 
  candidates = [ "#{controller.controller_name}", 
                 "#{controller.controller_name}_#{controller.action_name}" ]
 
  candidates.inject("") do |buf, css| 
    buf << stylesheet_link_tag(css) if FileTest.exist?("#{stylesheets_path}/#{css}.css")
    buf
  end
end


Compliments of Dema

Note: Anyone interested in this might also be interested in the bundled_resource plugin (google for it).

Render a partial to an instance variable

Normally, if you call "render_partial" within a controller, nothing but the partial will be rendered.

Occasionally, it is useful to render a partial to an instance variable as a string so that the view can still be rendered as normal, and the string can be passed in to the view.

  add_variables_to_assigns
  @content_for_navbar = @template.render_partial 'layouts/public_navbar'

Paginate an already-fetched result set (i.e. collection or array)

Sometimes it's nearly impossible to paginate a result set using the built-in :limit and :offset parameters of find(:all). Instead, you can fetch a complicated query and paginate the results afterward.

Add the following to application.rb:

  def paginate_collection(collection, options = {})
    default_options = {:per_page => 10, :page => 1}
    options = default_options.merge options
    
    pages = Paginator.new self, collection.size, options[:per_page], options[:page]
    first = pages.current.offset
    last = [first + options[:per_page], collection.size].min
    slice = collection[first...last]
    return [pages, slice]
  end


Call it from within your action like this:
@pages, @users = paginate_collection User.find_custom_query, :page => @params[:page]
« Newer Snippets
Older Snippets »
Showing 1-10 of 10 total  RSS