<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DZone Snippets: rails code</title>
    <link>http://snippets.dzone.com/posts</link>
    <pubDate>Fri, 25 Jul 2008 02:34:20 GMT</pubDate>
    <description>DZone Snippets: rails code</description>
    <item>
      <title>Make a remote URL work like a file upload (in Rails)</title>
      <link>http://snippets.dzone.com/posts/show/3994</link>
      <description>Want to load a remote URL into an acts_as_attachment/attachment_fu model?  Use this little utility class.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;  class UrlUpload&lt;br /&gt;    EXTENSIONS = {&lt;br /&gt;      "image/jpeg" =&gt; ["jpg", "jpeg", "jpe"],&lt;br /&gt;      "image/gif" =&gt; ["gif"],&lt;br /&gt;      "image/png" =&gt; ["png"]&lt;br /&gt;    }&lt;br /&gt;    attr_reader :original_filename, :attachment_data&lt;br /&gt;    def initialize(url)&lt;br /&gt;      @attachment_data = open(url)&lt;br /&gt;      @original_filename = determine_filename&lt;br /&gt;    end&lt;br /&gt;&lt;br /&gt;    # Pass things like size, content_type, path on to the downloaded file&lt;br /&gt;    def method_missing(symbol, *args)&lt;br /&gt;      if self.attachment_data.respond_to? symbol&lt;br /&gt;        self.attachment_data.send symbol, *args&lt;br /&gt;      else&lt;br /&gt;        super&lt;br /&gt;      end&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    private&lt;br /&gt;      def determine_filename&lt;br /&gt;        # Grab the path - even though it could be a script and not an actual file&lt;br /&gt;        path = self.attachment_data.base_uri.path&lt;br /&gt;        # Get the filename from the path, make it lowercase to handle those&lt;br /&gt;        # crazy Win32 servers with all-caps extensions&lt;br /&gt;        filename = File.basename(path).downcase&lt;br /&gt;        # If the file extension doesn't match the content type, add it to the end, changing any existing .'s to _&lt;br /&gt;        filename = [filename.gsub(/\./, "_"), EXTENSIONS[self.content_type].first].join(".") unless EXTENSIONS[self.content_type].any? {|ext| filename.ends_with?("." + ext) }&lt;br /&gt;        # Return the result&lt;br /&gt;        filename&lt;br /&gt;      end&lt;br /&gt;  end&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Now when you have the URL you want to load, do something like this:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;@model.uploaded_data = UrlUpload.new(url)&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Or better yet, make a pseudo-accessor on your aaa/attachment_fu model so you can stay "model-heavy".&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;def url=(value)&lt;br /&gt;  self.uploaded_data = UrlUpload.new(value)&lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Fri, 11 May 2007 18:04:51 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/3994</guid>
      <author>seancribbs (Sean Cribbs)</author>
    </item>
    <item>
      <title>Compress your ActiveRecord sessions</title>
      <link>http://snippets.dzone.com/posts/show/3924</link>
      <description>Using ActiveRecordStore and your sessions are getting too big?  Try this!&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;# in environment.rb or some file you require&lt;br /&gt;require 'zlib'&lt;br /&gt;CGI::Session::ActiveRecordStore::Session.class_eval {&lt;br /&gt;  class &lt;&lt; self&lt;br /&gt;    def marshal_with_compression(data)&lt;br /&gt;      Zlib::Deflate.deflate(marshal_without_compression(data))&lt;br /&gt;    end&lt;br /&gt;    def unmarshal_with_compression(data)&lt;br /&gt;      unmarshal_without_compression(Zlib::Inflate.inflate(data))&lt;br /&gt;    end&lt;br /&gt;    alias_method_chain :marshal, :compression&lt;br /&gt;    alias_method_chain :unmarshal, :compression&lt;br /&gt;  end&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;# in migration&lt;br /&gt;def self.up&lt;br /&gt;  change_column :sessions, :data, :binary&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;def self.down&lt;br /&gt;  change_column :sessions, :data, :text&lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Fri, 27 Apr 2007 16:11:46 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/3924</guid>
      <author>seancribbs (Sean Cribbs)</author>
    </item>
    <item>
      <title>Export Adobe FDF and XFDF from ActiveRecord</title>
      <link>http://snippets.dzone.com/posts/show/3487</link>
      <description>I needed to export XFDF from an application.  This code is kind of untested, but is based on the solution I came up with.  I would appreciate responses/modifications.  It's very straightforward mixin stuff, for the most part.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;# (X)FDF Export for ActiveRecord&lt;br /&gt;# Based on Justin Koivisto's FDF library for PHP&lt;br /&gt;# Author: Sean Cribbs, seancribbs_AT_gmail_DOT_com, http://seancribbs.com&lt;br /&gt;module FDF&lt;br /&gt;  def self.included(base)&lt;br /&gt;    base.extend ClassMethods&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  module ClassMethods&lt;br /&gt;    # Options:&lt;br /&gt;    #  &lt;tt&gt;:filename&lt;/tt&gt; - The filename of the associated PDF document.  REQUIRED!&lt;br /&gt;    #  &lt;tt&gt;:indentation&lt;/tt&gt; - How much to indent the resulting XFDF (XML)&lt;br /&gt;    #  &lt;tt&gt;:include&lt;/tt&gt; - Which associated models to include in the generated XFDF.&lt;br /&gt;    #  &lt;tt&gt;:exclude_attributes&lt;/tt&gt; - Which attributes of the current model should not be exported.  By default all non-internal attributes are exported (i.e. everything but _id fields).&lt;br /&gt;    #  &lt;tt&gt;:include_attributes&lt;/tt&gt; - Which attributes of the current model should be exported in addition to the default. By default all non-internal attributes are exported (i.e. everything but _id fields).&lt;br /&gt;    #  &lt;tt&gt;:attributes&lt;/tt&gt; - Override which attributes to export.&lt;br /&gt;    def exports_xfdf(options = {})&lt;br /&gt;      raise ArgumentError, "A :filename option must be specified." unless options[:filename]&lt;br /&gt;      options[:indentation] ||= 2&lt;br /&gt;      options[:include] = options[:include].is_a?(Array) ? options[:include] : [options[:include]].compact&lt;br /&gt;      unless included_modules.include? XFDFMethods&lt;br /&gt;        class_inheritable_accessor :xfdf_options&lt;br /&gt;        extend ClassMethods&lt;br /&gt;        include XFDFMethods&lt;br /&gt;      end&lt;br /&gt;      self.xfdf_options = options&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    # Options:&lt;br /&gt;    #  &lt;tt&gt;:filename&lt;/tt&gt; - The filename of the associated PDF document.  REQUIRED!&lt;br /&gt;    #  &lt;tt&gt;:include&lt;/tt&gt; - Which associated models to include in the generated FDF.&lt;br /&gt;    #  &lt;tt&gt;:exclude_attributes&lt;/tt&gt; - Which attributes of the current model should not be exported.  By default all non-internal attributes are exported (i.e. everything but _id fields).&lt;br /&gt;    #  &lt;tt&gt;:include_attributes&lt;/tt&gt; - Which attributes of the current model should be exported in addition to the default. By default all non-internal attributes are exported (i.e. everything but _id fields).&lt;br /&gt;    #  &lt;tt&gt;:attributes&lt;/tt&gt; - Override which attributes to export.&lt;br /&gt;    def exports_fdf(options = {})&lt;br /&gt;      raise ArgumentError, "A :filename option must be specified." unless options[:filename]&lt;br /&gt;      options[:include] = options[:include].is_a?(Array) ? options[:include] : [options[:include]].compact&lt;br /&gt;      unless included_modules.include? FDFMethods&lt;br /&gt;        class_inheritable_accessor :fdf_options&lt;br /&gt;        extend ClassMethods&lt;br /&gt;        include FDFMethods&lt;br /&gt;      end&lt;br /&gt;      self.fdf_options = options&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  module XFDFMethods&lt;br /&gt;    def to_xfdf(options = {})&lt;br /&gt;      options.reverse_merge! self.class.xfdf_options&lt;br /&gt;      fields = Util.collect_values(self, self.class.content_columns.map(&amp;:name), options)&lt;br /&gt;      filename = options[:filename]&lt;br /&gt;      xml = Builder::XmlMarkup.new :indentation =&gt; options[:indentation]&lt;br /&gt;      xml.instruct!&lt;br /&gt;      xml.xfdf("xmlns" =&gt; "http://ns.adobe.com/xfdf/", "xml:space" =&gt; "preserve") {&lt;br /&gt;        xml.f :href =&gt; filename&lt;br /&gt;        xml.fields {&lt;br /&gt;          fields.each do |field, value|&lt;br /&gt;            xml.field(:name =&gt; field) {&lt;br /&gt;              if value.is_a? Array&lt;br /&gt;                  value.each {|item| xml.value(item.to_s) }&lt;br /&gt;              else&lt;br /&gt;                xml.value(value.to_s)&lt;br /&gt;              end&lt;br /&gt;            }&lt;br /&gt;          end&lt;br /&gt;        }&lt;br /&gt;      }&lt;br /&gt;      xml.target!&lt;br /&gt;    end    &lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  module FDFMethods&lt;br /&gt;    def to_fdf(options={})&lt;br /&gt;      options.reverse_merge! self.class.fdf_options&lt;br /&gt;      fields = Util.collect_values(self, self.class.content_columns.map(&amp;:name), options)&lt;br /&gt;      filename = options[:filename]&lt;br /&gt;      data = "%FDF-1.2\n%&#226;&#227;&#65533;?&#211;\n1 0 obj\n&lt;&lt; \n/FDF &lt;&lt; /Fields [ "&lt;br /&gt;      fields.each do |field, value|&lt;br /&gt;        if value.is_a? Array&lt;br /&gt;          data &lt;&lt; "&lt;&lt;/T(#{field})/V["&lt;br /&gt;          value.each {|v| data &lt;&lt; "(#{v.strip})"}&lt;br /&gt;          data &lt;&lt; "]&gt;&gt;"&lt;br /&gt;        else&lt;br /&gt;          data &lt;&lt; "&lt;&lt;/T(#{field})/V(#{value.strip})&gt;&gt;"&lt;br /&gt;        end&lt;br /&gt;      end&lt;br /&gt;    end&lt;br /&gt;    data &lt;&lt; "] \n/F (#{filename}) /ID [ &lt;#{MD5.md5(Time.now).to_s}&gt;\n ] &gt;&gt;" &lt;&lt;&lt;br /&gt;            " \n&gt;&gt; \nendobj\ntrailer\n" &lt;&lt; "&lt;&lt;\n/Root 1 0 R \n\n&gt;&gt;\n%%EOF\n"&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  module Util&lt;br /&gt;    def self.collect_values(object, defaults, options = {})&lt;br /&gt;      attrs = []&lt;br /&gt;      if options[:attributes]&lt;br /&gt;        attrs = stringify_all(options[:attributes]) rescue []&lt;br /&gt;      else        &lt;br /&gt;        [:include_attributes, :exclude_attributes].each do |opt|&lt;br /&gt;          options[opt] = stringify_all(options[opt]) rescue []&lt;br /&gt;        end&lt;br /&gt;        attrs = stringify_all(defaults) + options[:include_attributes] - options[:exclude_attributes]&lt;br /&gt;      end&lt;br /&gt;      fields = attrs.inject({}) do |hash, key|&lt;br /&gt;        value = object.send(key) rescue nil&lt;br /&gt;        hash.merge key =&gt; value&lt;br /&gt;      end&lt;br /&gt;      fields.merge collect_association_values(object, options)&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def self.collect_association_values(object, options = {})&lt;br /&gt;      return {} if options[:include].blank?&lt;br /&gt;      values = {}&lt;br /&gt;      options[:include].each do |association|&lt;br /&gt;        unless object.send(association).blank?&lt;br /&gt;          models = object.send(association)&lt;br /&gt;          unless models.is_a? Array&lt;br /&gt;            columns = models.class.content_columns.map(&amp;:name)&lt;br /&gt;            values.merge! association_dump(association, models, columns)&lt;br /&gt;          else&lt;br /&gt;            models.each_with_index do |model, index|&lt;br /&gt;              columns = model.class.content_columns.map(&amp;:name)&lt;br /&gt;              values.merge! association_dump("#{association.singularize}_#{index+1}", model, columns)&lt;br /&gt;            end&lt;br /&gt;          end&lt;br /&gt;        end&lt;br /&gt;      end&lt;br /&gt;      values&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def self.association_dump(prefix, object, attributes)&lt;br /&gt;      attributes.inject({}) do |hash, attr|&lt;br /&gt;        value = object.send(attr) rescue nil&lt;br /&gt;        hash.merge "#{prefix}_#{attr}" =&gt; value&lt;br /&gt;      end&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def self.stringify_all(ary)&lt;br /&gt;      ary.compact.map(&amp;:to_s).uniq&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;ActiveRecord::Base.send :include, FDF&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Also available from: http://pastie.caboo.se/38835</description>
      <pubDate>Sat, 10 Feb 2007 00:43:34 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/3487</guid>
      <author>seancribbs (Sean Cribbs)</author>
    </item>
    <item>
      <title>Home-brewed file upload in Ruby on Rails</title>
      <link>http://snippets.dzone.com/posts/show/1805</link>
      <description>Most of this comes from others' work, but I was able to tool it to my needs and fix some bugs.  All of these lines go in the model, which for me has a :file and :content_type attributes.  :file stores the complete path to the uploaded file.  Be sure to change the string in path_to_file to the place where you want files stored, and that proper permissions are set on that path.  Also, sanitize_filename doesn't HAVE to be a private method -- make it public if you want.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;### Model ###&lt;br /&gt; def file=(uploaded_file)  &lt;br /&gt;    @uploaded_file = uploaded_file&lt;br /&gt;    @filename = sanitize_filename(@uploaded_file.original_filename)&lt;br /&gt;    write_attribute("content_type", @uploaded_file.content_type)&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  def after_create&lt;br /&gt;    if !File.exists?(File.dirname(path_to_file))&lt;br /&gt;      Dir.mkdir(File.dirname(path_to_file))&lt;br /&gt;    end&lt;br /&gt;    if @uploaded_file.instance_of?(Tempfile)&lt;br /&gt;      FileUtils.copy(@uploaded_file.local_path, path_to_file)&lt;br /&gt;    else&lt;br /&gt;      File.open(self.path_to_file, "wb") { |f| f.write(@uploaded_file.read) }&lt;br /&gt;    end&lt;br /&gt;    write_attribute("file", path_to_file)&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  def after_destroy&lt;br /&gt;    if File.exists?(self.file)&lt;br /&gt;      File.delete(self.file)&lt;br /&gt;      Dir.rmdir(File.dirname(self.file))&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  def path_to_file&lt;br /&gt;    File.expand_path("#{RAILS_ROOT}/upload/#{self.id}/#{@filename}")&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  private&lt;br /&gt;  def sanitize_filename(file_name)&lt;br /&gt;    # get only the filename, not the whole path (from IE)&lt;br /&gt;    just_filename = File.basename(file_name) &lt;br /&gt;    # replace all none alphanumeric, underscore or perioids with underscore&lt;br /&gt;    just_filename.gsub(/[^\w\.\_]/,'_') &lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;### View ###&lt;br /&gt;...&lt;br /&gt;&lt;input type="file" name="model[file]" /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Thu, 30 Mar 2006 02:33:29 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/1805</guid>
      <author>seancribbs (Sean Cribbs)</author>
    </item>
  </channel>
</rss>
