Posts Tagged ‘rails’

has_many_polymorphs and rails weirdness

When using has_many_polymorphs tagging generator, it will create appropriate Tag and Tagging models. However, if one uses this generator BEFORE using, say, rspec_scaffold for the same two models, Rails bails with

The name ‘PopulationTag’ is reserved by Ruby on Rails.
Please choose an alternative and run this generator again.

This confused me in the beginning! However, to overcome this, simply rename your model files before running the rspec_scaffold generator (of course renaming them back afterwards).

To workaround this issue in the first place, be sure to generate rspec_scaffolds BEFORE using the tagging generator that comes with has_many_polymorphs

a monkey’s stylable button_to

  def button_to(name, options = {}, html_options = {}, additional_content = "", descriptor_container = :span)

    html_options = html_options.stringify_keys
    convert_boolean_attributes!(html_options, %w( disabled ))

    method_tag = ''
    if (method = html_options.delete('method')) && %w{put delete}.include?(method.to_s)
     method_tag = tag(
       :input,
       :type => 'hidden',
       :name => '_method',
       :value => method.to_s
     )
    end

    form_id = (f_id = html_options.delete('form_id')) ? "id='#{f_id}'" : ""
    form_method = method.to_s == 'get' ? 'get' : 'post'

    request_token_tag = ''
    if form_method == 'post' && protect_against_forgery?
     request_token_tag = tag(
       :input,
       :type => "hidden",
       :name => request_forgery_protection_token.to_s,
       :value => form_authenticity_token
     )
    end

    if confirm = html_options.delete("confirm")
     html_options["onclick"] = "return #{confirm_javascript_function(confirm)};"
    end

    url = escape_once(options.is_a?(String) ? options : self.url_for(options))
    name ||= url

    descriptor = content_tag(descriptor_container.to_s, name, html_options)

    button_options = { "name" => "#{name.underscore}", "value" => name }
    button_id = html_options.delete("button_id")
    button_type = html_options.delete("button_type")
    button_options.merge!("id" => button_id) if button_id
    button_options.merge!("type" => button_type) if button_type

    form =  "
” form << "
” form << " #{method_tag}" form << " #{request_token_tag}" form << " #{content_tag("button", descriptor, button_options) }" form << "
” form << additional_content form << "
” form end

polymorphic link_to

# Why didn't I try out earlier if this is possible? Well, it is!

<%= link_to("Show", [ @foo, @bar ]) %>

truncate in active record models

# Put this in a config/initializers file e.g. config/initializers/truncate_helper.rb
# to make truncate available to all ActiveRecord::Base models

# credits for truncate go to:
# http://daniel.collectiveidea.com/blog/2007/7/10/a-prettier-truncate-helper

class ActiveRecord::Base

  # Awesome truncate
  # taken from http://daniel.collectiveidea.com/blog/2007/7/10/a-prettier-truncate-helper
  # -------------------------------------------------------------------------------------
  # First regex truncates to the length, plus the rest of that word, if any.
  # Second regex removes any trailing whitespace or punctuation (except ;).
  # Unlike the regular truncate method, this avoids the problem with cutting
  # in the middle of an entity ex.: truncate("this & that",9)  => "this &am..."
  # though it will not be the exact length.
  def truncate(text, length = 30, truncate_string = "...")
    return if text.nil?
    l = length - truncate_string.chars.length
    text.chars.length > length ? text[/\A.{#{l}}\w*\;?/m][/.*[\w\;]/m] + truncate_string : text
  end
end

treetop >= 1.2.3 works nice with rails

treetop-1.2.3 and polyglot-0.2.1 solve the problems treetop previously had when used from a rails app. The dependencies on ruby facets were removed, and the load_error bug was fixed in polyglot

treetop-1.2.2 rails workaround

This was originally posted to the treetop-development group on google

First of all thx a lot for this wonderful treetop! Now I can finally
start to write small parsers because it’s the ruby I love :)

Anyways, here are my comments on the issues encountered by Nick. (I
use treetop from within a rails app)
I admit I didn’t have to dig as deep as him (thx for all the digging
and the post in this group, it saved HOURS for me most probably!)

1) To get my app running in development mode, I had to comment out the
following in treetop-1.2.2/lib/treetop.rb

# require “facets/stylize”

The funny thing is, if I don’t do that, it doesn’t break my whole app
like Nick said, but only some of my calls to
skip_before_filter which don’t stop the before_filters from
being executed anymore (The only failure I noticed in my app, was that
I couldn’t access actions that relied on skipping a before_filter that
was defined in ApplicationController – then again, my
SessionControllerlogin/logout actions – relied on that very
behavior … and didn’t break :-) … I definitely assume that there
is no real problem with rails before_filters in general, but that this
also has something to do with problems related to constant loading
(i.e. camelize), still it’s funny that this seems to impact my app
only in this one scenario …

2) To get my app running in production mode though, I had to comment
out the following in treetop-1.2.2/lib/treetop.rb

# require “facets/stylize”
# require “polyglot”
# Polyglot.register([“treetop”, “tt”], Treetop)

I suppose this doesn’t lead to any problems, since these libs are only
necessary for generating the parser and not for executing it? The
thing here is that polyglot obviously offends rails’ production mode,
since both mongrel and thin both barf on me when I try to access any
actions.

To be more specific, if I require the .treetop file (as should be
possible thx to polyglot), then my server won’t start at all, telling
me friendly things like

../polyglot-0.2.0/lib/polyglot.rb:35:in
`load’: undefined local variable or method `load_error’ for
Polyglot:Module (NameError)

If I load the grammar via Treetop.load, the server starts up, but fails
on every action (the first failure is the same as the above, after
this all subsequent failures seem to be rooted in
load_missing_constant errors most probably due to the behavior that
Nick mentioned.

So for all that are experiencing similar problems:

My current workflow is to leave the require statements on my dev box
while I’m working on the grammar (knowing that I cannot access my app
properly during that time), and having them commented out in the
treetop installation on my production server (and also when I’m
accessing my app on my dev box)

subtleties in acts_as_list :scope definitions

# ALWAYS USE '...' instead of "..."
# ---------------------------------
# interpolation will happen later
# when the instance variables are
# in scope (eval magic)

acts_as_list :scope => 'foo_id = #{foo_id} AND bar_id = #{bar_id}'

acts_as_list helper

# include this in application.rb
# or only in the controllers you need it.
# USAGE
# class FooParents::FoosController < ApplicationController
#   include ActsAsListHelper
#   protected
#   def load_foo_parent
#     @foo_parent = FooParent.find(params[:foo_parent_id])
#   end
#   public
#   def create
#     @foo = @foo_parent.foos.build(params[:foo])
#     if @foo.save
#       update_positions :foo_parent, :foo
#       # ...
#     else
#       # ...
#     end
#   end
#   def update
#     @foo = @foo_parent.foos.find(params[:id])
#     update_positions :foo_parent, :foo
#     if @foo.save
#       # ...
#     else
#       # ...
#     end
#   end
#   #...
# end

module ActsAsListHelper
  # support acts_as_list
  def update_positions(parent_name, resource_name)
    parent = instance_variable_get("@#{parent_name.to_s}")
    resource = instance_variable_get("@#{resource_name.to_s}")

    desired_position = params[resource_name.to_sym][:position].to_i
    nr_of_nested_resources = parent.send(resource_name.to_s.pluralize).size

    if desired_position > nr_of_nested_resources + 1 || desired_position < 1
      # correct values that are out of list bounds
      position = nr_of_nested_resources + 1
    else
      position = desired_position
    end
    # acts_as_list call
    resource.insert_at(position)
  end
end

Fix bleakhouse for edgerails >= changeset/8664

# Apparently http://dev.rubyonrails.org/changeset/8664 broke bleakhouse feature detection!
# To make bleakhouse work with edgerails >= 8664 you will have to
# patch bleakhouse-3.7/lib/bleakhouse/rails/dispatcher.rb

# Insert callbacks so that each request makes before-and-after usage snapshots.
class Dispatcher

  # rely on refactoring in http://dev.rubyonrails.org/changeset/8664
  if self.included_modules.include?(ActiveSupport::Callbacks)
    # Rails 2.0

    def core_rails_snapshot
      BleakHouse::Rails::MEMLOGGER.snapshot(
        BleakHouse::Rails::LOGFILE, 'core rails',
        BleakHouse::Rails::WITH_SPECIALS,
        BleakHouse::Rails::SAMPLE_RATE
      )
    end
    before_dispatch :core_rails_snapshot

    def controller_snapshot
      BleakHouse::Rails::MEMLOGGER.snapshot(
        BleakHouse::Rails::LOGFILE,
        BleakHouse::Rails.last_request_name || 'unknown',
        BleakHouse::Rails::WITH_SPECIALS,
        BleakHouse::Rails::SAMPLE_RATE
      )
    end
    after_dispatch :controller_snapshot

  else
    # Rails 1.2.x
    # ...
  end
end

checking for local variables in rails partials

# You cannot test whether a certain key
# (:somevar) was present in the locals
# hash passed to render using

defined?(:somevar),

# due to the way template compilation works in Rails.
# But you can use the following pattern instead:

local_assigns.include?(:somevar)

« Older Entries

Newer Entries »