Posts Tagged ‘merb’

authenticated flash upload using merb-auth and dm-paperclip

In order to get multiple file upload working, we decided to use flash. The problem with the flash upload library we used (uploadify — another alternative is swfupload), is that they both don’t send the session cookie to the server.

Since we have to authenticate our image uploads, we needed to get around this by following 2 steps:

  1. install the rack middleware from below (original code by Angel Pizarro, found via thewebfellas)
  2. send the raw cookie data as query parameter keyed by your apps session_id_key
# Merb.root/lib/rack/flash_upload.rb
module Merb
  module Rack
    class SetSessionCookieFromFlash < Merb::Rack::Middleware
      # :api: private
      def initialize(app, session_key = '_session_id')
        super(app)
        @session_key = session_key
      end
      # :api: plugin
      def call(env)
        if env["HTTP_USER_AGENT"] =~ /^(Adobe|Shockwave) Flash/
          params = Merb::Parse.query(env['QUERY_STRING'])
          if params[@session_key]
            env['HTTP_COOKIE'] = [@session_key, params[@session_key]].join('=').freeze
          end
        end
        @app.call(env)
      end
    end
  end
end

# Merb.root/config/rack.rb
require 'rack/flash_upload'
use Merb::Rack::SetSessionCookieFromFlash, Merb::Config[:session_id_key]

merb-helpers should produce valid html id attributes

A Ticket for this issue can be found here

# stick this in init.rb's before_app_loads block
# until this issue maybe gets resolved in merb-helpers
module Merb::Helpers::Form::Builder
  class Form < Base
    def update_unbound_controls(attrs, type)
      if attrs[:name] && !attrs[:id]
        # this makes sure that the '[]' characters which are not valid
        # in html ids, don't get copied over. furthermore, the trailing '_'
        # character makes sure that this id stays unique (particularly
        # necessary for additionally generated hidden inputs as they
        # are generated for checkboxes for example). the 'to_s' call
        # is necessary in order for the merb testsuite to run. obviously
        # there are some tests that use the Symbol :truez as a name
        # attribute, and since Symbol#gsub is private, tests fail if the
        # name attr isn't always converted to a String before use.
        attrs.merge!(:id => attrs[:name].to_s.gsub(/(\[|\])/, '_'))
      end
      case type
      when "text", "radio", "password", "hidden", "checkbox", "file"
        add_css_class(attrs, type)
      end
      super
    end
  end
end

relevant merb / datamapper ticket information

When filing a ticket for merb or datamapper, it’s a good idea to put the following information into the ticket
(Suggested by Dan Kubb - dkubb in #datamapper)

uname -a (for unixes at least)
ruby --version
mysql --version (or the equivalent for your db)
gem list '\A(?:(?:d[mo]|merb)[_-]|data_?(?:mapper|objects)|extlib)'

merb_resource_controller now supports nested (singleton) resources

merb_resource_controller is a merb plugin that provides the default CRUD actions for controllers and allows for easy customization of the generated actions. You might have already heard of or used one of its counterparts in rails world, like make_resourceful, James Golick’s resource_controller, Ian White’s resources_controller or other projects on github. Thx a lot for the inspiration guys!

As it so happens, today merb_resource_controller learned to work with arbitrarily nested (singleton) resources AND got a massive README update :-)

So if you are a  merbivore you should really check it out and give me feedback!

What’s left to say? I say let the code do the talking …

class Articles < Application
  controlling :articles
end

fun with merb -i and dm-sweatshop

# in spec/fixtures.rb
# of course these are just examples of what the content could look like
User.fix {{
  :login => /\w+/.gen,
  :password => (password = /\w{12}/.gen),
  :password_confirmation => password
}}

GeoPoint.fix {{
  :lat => BigDecimal.new((rand * 180 -  90).to_s),
  :lng => BigDecimal.new((rand * 360 - 180).to_s),
}}

Location.fix {{
  :geo_point => unique { GeoPoint.gen },
  :name => /\w+/.gen,
  :short_description => /\w+/.gen,
  :long_description => /\w+/.gen,
  :address => /\w+/.gen
}}

20.times { Location.gen }

# in config/init.rb
Merb::BootLoader.after_app_loads do

  # This will get executed after your app's classes have been loaded.

  if Merb.env == "development"
    # allows for easy playin around in merb -i
    # dm-sweatshop will provide enough data for that
    require Merb.root / "spec" / "spec_fixtures"
  end

end