Best ruby-on-rails questions in March 2011

Protect sensitive attributes w/ declarative_authorization

14 votes

Whats a cool way to protect attributes by role using declarative_authorization? For example, a user can edit his contact information but not his role.

My first inclination was to create multiple controller actions for different scenarios. I quickly realized how unwieldy this could become as the number of protected attributes grows. Doing this for user role is one thing, but I can imagine multiple protected attributes. Adding a lot controller actions and routes doesn't feel right.

My second inclination was to create permissions around specific sensitive attributes and then wrap the form elements with View hepers provided by declarative_authorizations. However, the model and controller aspect of this is a bit foggy in my mind. Suggestions would be awesome.

Please advise on the best way to protect attributes by role using declaritive_authorizations ... thanks

EDIT 2011-05-22
Something similar is now in Rails as of 3.1RC https://github.com/rails/rails/blob/master/activerecord/test/cases/mass_assignment_security_test.rb so I would suggest going that route now.

ORIGINAL ANSWER
I just had to port what I had been using previously to Rails 3. I've never used declarative authorization specifically, but this is pretty simple and straightforward enough that you should be able to adapt to it.

Rails 3 added mass_assignment_authorizer, which makes this all really simple. I used that linked tutorial as a basis and just made it fit my domain model better, with class inheritance and grouping the attributes into roles.

In model

acts_as_accessible :admin => :all, :moderator => [:is_spam, :is_featured]
attr_accessible :title, :body # :admin, :moderator, and anyone else can set these

In controller

post.accessed_by(current_user.roles.collect(&:code)) # or however yours works
post.attributes = params[:post]

lib/active_record/acts_as_accessible.rb

# A way to have different attr_accessible attributes based on a Role
# @see ActsAsAccessible::ActMethods#acts_as_accessible
module ActiveRecord
  module ActsAsAccessible
    module ActMethods
      # In model
      # acts_as_accessible :admin => :all, :moderator => [:is_spam]
      # attr_accessible :title, :body
      #
      # In controller
      # post.accessed_by(current_user.roles.collect(&:code))
      # post.attributes = params[:post]
      #
      # Warning: This frequently wouldn't be the concern of the model where this is declared in,
      # but it is so much more useful to have it in there with the attr_accessible declaration.
      # OHWELL.
      #
      # @param [Hash] roles Hash of { :role => [:attr, :attr] }
      # @see acts_as_accessible_attributes
      def acts_as_accessible(*roles)
        roles_attributes_hash = Hash.new {|h,k| h[k] ||= [] }
        roles_attributes_hash = roles_attributes_hash.merge(roles.extract_options!).symbolize_keys

        if !self.respond_to? :acts_as_accessible_attributes
          attr_accessible
          write_inheritable_attribute :acts_as_accessible_attributes, roles_attributes_hash.symbolize_keys
          class_inheritable_reader    :acts_as_accessible_attributes

          # extend ClassMethods unless (class << self; included_modules; end).include?(ClassMethods)
          include InstanceMethods unless included_modules.include?(InstanceMethods)
        else # subclass
          new_acts_as_accessible_attributes = self.acts_as_accessible_attributes.dup
          roles_attributes_hash.each do |role,attrs|
            new_acts_as_accessible_attributes[role] += attrs
          end
          write_inheritable_attribute :acts_as_accessible_attributes, new_acts_as_accessible_attributes.symbolize_keys
        end
      end
    end

    module InstanceMethods
      # @param [Array, NilClass] roles Array of Roles or nil to reset
      # @return [Array, NilClass]
      def accessed_by(*roles)
        if roles.any?
          case roles.first
          when NilClass
            @accessed_by = nil
          when Array
            @accessed_by = roles.first.flatten.collect(&:to_sym)
          else
            @accessed_by = roles.flatten.flatten.collect(&:to_sym)
          end
        end
        @accessed_by
      end

      private
      # This is what really does the work in attr_accessible/attr_protected.
      # This override adds the acts_as_accessible_attributes for the current accessed_by roles.
      # @see http://asciicasts.com/episodes/237-dynamic-attr-accessible
      def mass_assignment_authorizer
        attrs = []
        if self.accessed_by
          self.accessed_by.each do |role|
            if self.acts_as_accessible_attributes.include? role
              if self.acts_as_accessible_attributes[role] == :all
                return self.class.protected_attributes
              else
                attrs += self.acts_as_accessible_attributes[role]
              end
            end
          end
        end
        super + attrs
      end
    end
  end
end

ActiveRecord::Base.send(:extend, ActiveRecord::ActsAsAccessible::ActMethods)

spec/lib/active_record/acts_as_accessible.rb

require 'spec_helper'

class TestActsAsAccessible
  include ActiveModel::MassAssignmentSecurity
  extend ActiveRecord::ActsAsAccessible::ActMethods
  attr_accessor :foo, :bar, :baz, :qux
  acts_as_accessible :dude => [:bar], :bra => [:baz, :qux], :admin => :all
  attr_accessible :foo
  def attributes=(values)
    sanitize_for_mass_assignment(values).each do |k, v|
      send("#{k}=", v)
    end
  end
end

describe TestActsAsAccessible do
  it "should still allow mass assignment to accessible attributes by default" do
    subject.attributes = {:foo => 'fooo'}
    subject.foo.should == 'fooo'
  end
  it "should not allow mass assignment to non-accessible attributes by default" do
    subject.attributes = {:bar => 'baaar'}
    subject.bar.should be_nil
  end
  it "should allow mass assignment to acts_as_accessible attributes when passed appropriate accessed_by" do
    subject.accessed_by :dude
    subject.attributes = {:bar => 'baaar'}
    subject.bar.should == 'baaar'
  end
  it "should allow mass assignment to multiple acts_as_accessible attributes when passed appropriate accessed_by" do
    subject.accessed_by :bra
    subject.attributes = {:baz => 'baaaz', :qux => 'quuux'}
    subject.baz.should == 'baaaz'
    subject.qux.should == 'quuux'
  end
  it "should allow multiple accessed_by to be specified" do
    subject.accessed_by :dude, :bra
    subject.attributes = {:bar => 'baaar', :baz => 'baaaz', :qux => 'quuux'}
    subject.bar.should == 'baaar'
    subject.baz.should == 'baaaz'
    subject.qux.should == 'quuux'
  end
  it "should allow :all access" do
    subject.accessed_by :admin
    subject.attributes = {:bar => 'baaar', :baz => 'baaaz', :qux => 'quuux'}
    subject.bar.should == 'baaar'
    subject.baz.should == 'baaaz'
    subject.qux.should == 'quuux'
  end
end

Rails: Why can't you set an association to nil in a where clause?

9 votes

So, I have photos that belong to collections and users. Photos always belong to a user, but may not be assigned to a collection.

In my controller, this works perfectly:

@collection_photos = Photo.where( :collection => @collection, :user => current_user )

However, this fails...

@other_photos = Photo.where( :collection => nil, :user => current_user )

...but this works:

@other_photos = Photo.where( :collection_id => nil, :user => current_user )

When collection is set to nil I get this error message: No attribute named 'collection' exists for tablephotos``

So, if I pass an object it knows to search for collection_id from the symbol :collection, but if I don't pass an object it doesn't seem to be aware of the association.

Am I understanding this correctly? Could anyone explain a little better why :collection=>nil doesn't work?

when you use pass in the conditions into ActiveRecord, it actually tries to analyze the objects that you passed in, is it a string? an array? a hash? and what's in the string, array or hash?

and in your case, a hash, so it's trying to analyze what's in the hash, in the first statement (which works), you passed in a model instance as the value, so it tries to find if there are any associations that mapped to the key your specified and voila, it found it and everything works as planned

in the second case, you passed in nil as the value, now, ActiveRecord sees that it's a nil object, so it decided that it's not an association. note that it doesn't look at the key, but it only looked at the value, thus it tries to find if there's any column that mapped to the key, but it couldn't find, returning an error

in the last case, you passed in nil as the value, same thing, it tried to find a column which mapped to :collection_id, thus it passed in nil as the value in the SQL statement, and it returned successfully

so it's just an unfortunate considerations taken by ActiveRecord that makes the second case not working =)

hope this clarifies! =D

Rails for Zombies Lab 4 > Exercise 3

9 votes

Hi!
I stucked in the fourth Rails for Zombies lab at the third exercise. This is my task: Create action that will create a new Zombie and then redirect to the created zombie's show page. I've got the following params array:

params = { :zombie => { :name => "Greg", :graveyard => "TBA" } }

I wrote the following code as a solution:

def create
   @zombie = Zombie.create   
   @zombie.name = params[ :zombie [ :name ] ]   
   @zombie.graveyard = params[ :zombie [ :graveyard ] ]
   @zombie.save   

   redirect_to(create_zombie_path)
end

But when I submit it I got the following error:
#<TypeError: can't convert Symbol into Integer>

I know that I made a mistake but I cannot figure out where. Please help me.

def create
   @zombie = Zombie.create(params[:zombie])
   redirect_to @zombie
end

SessionsHelper in railstutorial.org: Should helpers be general-purpose modules for code not needed in views?

9 votes

railstutorial.org has a suggestion which strikes me as a little odd.

It suggests this code:

class ApplicationController < ActionController::Base 
  protect_from_forgery 
  include SessionsHelper 
end 

The include SessionsHelper makes the methods available from ApplicationController, yes, but it makes them available in any view, as well. I understand that authentication/authorization is cross-cutting, but is this really the best place?

That seems to me to be potentially too broad of a scope. Putting code which implements, say, a before_filter which conditionally redirects (as the railstutorial.org example does) in a module which more commonly contains view helpers seems surprising.

Would functionality not strictly needed in views be better placed in ApplicationController or elsewhere?

Or am I just thinking too much about this?

Indeed, your feeling is correct imho.

I would implement this the other way round: add the functions sign_in and current_user to ApplicationController (or if you really want to: in a separate module defined in lib and include it), and then make sure that the current_user method is available in the view.

In short:

class ApplicationController

  helper :current_user

  def sign_in

  end

  def current_user
    @current_user ||= user_from_remember_token
  end
end

Of course, if you have a lot of code to place into your ApplicationController it can get messy. In that case I would create a file lib\session_management.rb:

module SessionManagement
  def self.included(base)
    base.helper :current_user
  end

  def sign_in
    ..
  end

  def current_user
    ..
  end
end

and inside your controller you can then just write:

class ApplicationController
  include SessionManagement
end

Hope this helps. end

auto_complete_for: prevent the first item from being auto-selected

8 votes

The auto_complete_for dealio from script.aculo.us is great an all, but is there a way for me to selectively disable the fact that it always auto-selects the first item in the list?

The problem is that, if I want to type my own entry that is new, and novel, I don't want the first item in the list to be auto-selected. The reason is because when I TAB out of the field, it selects, and fills the text box with that first item.

I got around that, somewhat, by making the first item in the list the same as what I'm typing, but that's not perfect either, because the auto_complete list doesn't always update with every keystroke, depending on how fast I type. I've tried setting the list refresh rate to the lowest value (1 millisecond) but no go.

What I really want is an option in "auto_complete_for" that doesn't select that first item at all - the same way that Google Instant doesn't automatically select the first suggested search phrase - you have to arrow-down to select one.

Maybe I can do this via an HTML option that I'm missing?

Looking at the source, there doesn't appear to be an option for that, but I bet if you changed line 284 of controls.js to this.index = -1; it would do what you want.

Otherwise, it might be time to look for a different autocomplete widget.

STI, one controller

7 votes

Hi! I'm new to rails and I'm kind of stuck with this design problem, that might be easy to solve, but I don't get anywhere: I have two different kinds of advertisements: highlights and bargains. Both of them have the same attributes: title, description and one image (with paperclip). They also have the same kind of actions to apply on them: index, new, edit, create, update and destroy.

I set a STI like this:

Ad Model: ad.rb

class Ad < ActiveRecord::Base
end

Bargain Model: bargain.rb

class Bargain < Ad
end

Highlight Model: highlight.rb

class Highlight < Ad
end

The problem is that I'd like to have only one controller (AdsController) that executes the actions I said on bargains or highlights depending on the URL, say www.foo.com/bargains[/...] or www.foo.com/highlights[/...].

For example:

  • GET www.foo.com/highlights => a list of all the ads that are highlights.
  • GET www.foo.com/highlights/new => form to create a new highlight etc...

How can i do that?

Thanks!

Hi!

First. Add some new routes:

resources :highlights, :controller => "ads", :type => "Highlight"
resources :bargains, :controller => "ads", :type => "Bargain"

And fix some actions in AdsController. For example:

def new
  @ad = Ad.new()
  @ad.type = params[:type]
end

For best approach for all this controller job look this comment

That's all. Now you can go to localhost:3000/highlights/new and new Highlight will be initialized.

Index action can look like this:

def index
  @ads = Ad.where(:type => params[:type])
end

Go to localhost:3000/highlights and list of highlights will appear.
Same way for bargains: localhost:3000/bargains

etc

URLS

<%= link_to 'index', :highlights %>
<%= link_to 'new', [:new, :highlight] %>
<%= link_to 'edit', [:edit, @ad] %>
<%= link_to 'destroy', @ad, :method => :delete %>

for being polymorphic :)

<%= link_to 'index', @ad.class %>

I am looking to start developing a relatively simple web application that will pull data from various sources and normalizing it. A user can also enter the data directly into the site. I anticipate hitting scale, if successful. Is it worth putting in the time now to use scalable or distributed technologies or just start with a LAMP stack? Framework or not? Any thoughts, suggestions, or comments would help.

Disregard my vague description of the idea, I'd love to share once I get further along.

Is it worth putting in the time now to use scalable or distributed technologies or just start with a LAMP stack?

A LAMP stack is scalable. Apache provides many, many alternatives.

Framework or not?

Always use the highest-powered framework you can find. Write as little code as possible. Get something in front of people as soon as you can.

Focus on what's important: Get something to work.

If you don't have something that works, scalability doesn't matter, does it?

Then read up on optimization. http://c2.com/cgi/wiki?RulesOfOptimization is very helpful.

Rule 1. Don't.

Rule 2. Don't yet.

Rule 3. Profile before Optimizing.

Until you have a working application, you don't know what -- specific -- thing limits your scalability.

Don't assume. Measure.

That means build something that people actually use. Scale comes later.

Rails3 Google Maps testing with selenium

7 votes

Hi,

I'm trying to test a google maps app with Rails3. I'm using cucumber with capybara and selenium for javascript testing. I have a map where I wait for google maps to be loaded, and then send an ajax request to my server, where I get locations that I'm inserting into the map. I'm wondering if it's possible with selenium to wait until google maps is loaded, the ajax call to my server is finished and the marker are placed inside the map. The other issue is, how to select this marker within google maps. Are there any selectors?

Or should I go the other way, and use a JS testing framework like Jasmine to test if my classes are loaded and so on. I don't have any expirience with Jasmine, so is it possible to test a google maps?

Maybe someone knows a solution, or a hint if it's not possible, or a workaround or... ;)

thx so much, to this great community ;) tux

[UPDATE 1]

I've found out how to select markers in google maps. If you look at googles selenium tests you can check out what they are doing. For example selecting a marker:

waitForElementPresent   xpath=//img[contains(@src,'marker')]

But here comes the next problem. How do I select a specific marker? Is there a way inside the javascript google maps API to assign an ID to it, so that I can use #marker_1, #marker_2...?

And another strange thing is, that function like wait_for_element or wait_for_condition aren't available inside my cucumber step definitions. Are the google selenium tests using own function like that waitForElementPresent? Or are this standard selenium functions? I've found a lots of posts, where they always use something like

selenium.wait_for_condition
selenium.wait_for_element

or

@selenium.wait_for_condition
...

Inside my step definitions the selenium and the @selenium var a nil. How can I access this methods? I've also found this post, but it is from Oct. '08, so I think there must be a better solution (btw. this solution works on the first sight).

Like on this page, they give an overview of a few selenium methods how to wait for a condition or element. Is this still present? How can I use this functions?

regards, tux

[UPDATE 2]

Damn it, I've found out, that the selenium tests I mentioned above are for V2 of google maps, not for V3. I have tried it with

wait_until { page.has_xpath?("//img[contains(@src,'marker')]") }

But it doesn't work. The marker is visible on the map, but I get a timeout error, because with this XPath selector it is not found. I'm wondering if it is generally possible to select a marker out of the DOM.

I also tried to assign an additonal attribute to the marker when I create it:

// marker is the marker returned by google maps after adding it to the map
$(marker).attr('id', "marker_1");

But when I try to access it with the jQuery selector $("#marker_1"), it doesn't find it. So, still no solution, yet.

What I do with mine is to execute the calls in your step definitions like so:

page.execute_script("launchmap()")

then check for their existence in the page..then do your normal ajax check in capybara. the marker will be contained in a div right? then if you call launchmap and create the markers, capybara SHOULD be able find your markers

UPDATE

found out about this plugin: http://vigetlabs.github.com/jmapping/examples/

it gives you semantic markup for your google maps(for graceful degradation) allowing you to actually check if a marker exists using capybara. hope it helps(dont have time to test it but it looks promising)

How can I find open source projects to contribute to (Ruby, Rails)

7 votes

I'm a Ruby on Rails developer with a bit of time on my hands.

I would like to use this time to give back and learn by contributing to an open source project.

I'm not a top notch programmer and would like to start small.

Where can i find small open source projects in Ruby or Rails ? And how can I contribute ?

Alex

My advice is to look at the projects you use and really love, then get on their message boards and see what's needed. This is usually when people say "send me a pull request" or "send me a patch"

You can also look at a project's github "issues" tab. Any of these are generally something that can be worked on. You'll fork the project, make changes (and add tests), then send the maintainer a pull-request.

Anyway, long story short: work on something you love using.

Is there a clean way to avoid calling a method on nil in a nested params hash?

7 votes

I'm interested in getting the nested 'name' parameter of a params hash. Calling something like

params[:subject][:name]

throws an error when params[:subject] is empty. To avoid this error I usually write something like this:

if params[:subect] && params[:subject][:name]

Is there a cleaner way to implement this?

IMHO the best solution by far is Ick's maybe. You don't need to significantly change your code, just intersperse maybe proxies when necessary, explicit yet compact:

params[:subject].maybe[:name]

The same author (raganwald) also wrote the (probably best known) andand, but while it works very similar, I think that writing maybe is much nicer.

Rails: Scheduled task to warm up the cache?

6 votes

I am using the following to cache a slow loading page using memcached:

caches_action :complex_report, :expires_in => 1.day

The controller action is protected by Devise authentication.

The page currently gets cached the first time a user requests it. Subsequent request that day are then pulled from the cache.

The problem with this is that the initial request takes 20-30 seconds to load. Is it possible to populate the cache in advance by way of a scheduled task?

Any suggestions much appreciated.

Here is an expansion on the previous cron based solution which uses curl's ability to store cookies so that you can auth in one step and then use the cookie again as an authenticated user in the next step. So if you put these lines in a script called "prepare_cache.sh"

rm /tmp/cookiejar
curl --request POST -d "login=<username>" -d "password=<password>" -c /tmp/cookiejar http://yourwebpages.url/login
curl --request GET -b -c /tmp/cookiejar http://yourwebpages.url/page_to_cache
rm /tmp/cookiejar

replacing the login and password parameters with ones which match the variables used in your login form and obviously the urls to call. I'm removing the cookiejar before to make sure there isn't a file there already and removing it at the end to make sure there isn't a cookie floating about with access levels it shouldn't have.

Then you can call this script with the cron job:

*/15 * * * * /home/myname/prepare_cache.sh > /dev/null 2>&1

And hopefully that should work. Seemed to work for me when I tried it.

Rails article helper - "a" or "an"

6 votes

Does anyone know of a Rails Helper which can automatically prepend the appropriate article to a given string? For instance, if I pass in "apple" to the function it would turn out "an apple", whereas if I were to send in "banana" it would return "a banana"

I already checked the Rails TextHelper module but could not find anything. Apologies if this is a duplicate but it is admittedly a hard answer to search for...

None that I know of but it seems simple enough to write a helper for this right? Off the top of my head

def indefinite_articlerize(params_word)
    %w(a e i o u).include?(params_word[0].downcase) ? "an #{params_word}" : "a #{params_word}"
end

hope that helps

edit 1: Also found this thread with a patch that might help you bulletproof this more https://rails.lighthouseapp.com/projects/8994/tickets/2566-add-aan-inflector-indefinitize

Ruby on Rails: what performance can I realistically aim for?

6 votes

I've been building an application in Ruby on Rails 3, and I'm starting to worry about performance optimization. Now I hope that my question is not too subjective for this site, but I'm interested in facts, not a discussion, so here goes:

While I'm trying to get my views to render faster, there is one thing I simply do not know: What should I aim for? Given a reasonably complex page, what load time is realistic? I simply don't have any reference.

What I'm typically seeing for my application is something like this:

Completed 200 OK in 397ms (Views: 341.1ms | ActiveRecord: 17.7ms)

  • This is on my production server, running Apache/Passenger.

  • I am the only one (!) making requests on that server, it's a root server (not virtual), running Ubuntu, AMD Athlon 64 X2 5600+, 4 GB RAM

  • That is, for most of my more complicated actions (not unusually complicated, just assume it's a paginated listing of 20 objects with 5 computed properties each or something) the ActiveRecord times are almost always fine (<20-30ms), but the "views" number is usually >200 ms.

  • Now, to my question: When I started using RoR my expectation (maybe unrealistic) was that for most consumer-oriented applications with average complexity (let's say something like Facebook, Twitter, etc. WITHOUT the millions of users) I would get < 20 ms load times as long as I was the only one making requests, and that for a single server load times would only approach 100ms or more if there were lots of people making requests at the same time.

  • My expectation was also that database requests would be the major bottleneck, since all the rest is just relatively simple computations without any real complexity. I thought that it might take 10ms to get all the objects from the database, and then maybe another 5 ms to run the controller code, build the view, etc.

Since I've never been in charge of any production app, I don't know if this expectation was in any way realistic. So I would like somebody with experience point out to me what my realistic expectation should be.

  • (e.g. "pretty much everything but really nasty stuff should render in 50 ms tops as long as you are the only one making requests")
  • or ("actually 300 ms is not unusual for RoR applications, even if you're the only user")
  • or ("Are you kidding? I get < 10 ms with 150 concurrent requests on a smaller server than yours. There must be something very wrong with your app)

Again, I hope this is not too subjective, but I'm not really interested in an opinion of whether or not RoR is fast, I want facts from someone with more experience on what numbers are average and to be expected from production RoR applications. Otherwise I simply have no clue at what point I should stop optimizing and just accept that I'll never get 10 ms load times.

I'm getting view times < 20ms on a $20/month linode server. That's well-optimized code, for a request of medium complexity, running on JRuby. You haven't hit Rails' performance limits by any means. Time to use a profiler and see what's taking so long.

Sort values using a specific collation in Ruby/Rails

6 votes

Is it possible to sort an array of values using a specific collation in Ruby? I have a need to sort according to the da_DK collation.

Given the array %w(Aarhus Aalborg Assens) I would like to have ['Assens', 'Aalborg', 'Aarhus'] back which is the correct order in Danish.

The standard sort method

%w(Aarhus Aalborg Assens).sort

returns something that looks like the ascii order (at least not the Danish order):

["Aalborg", "Aarhus", "Assens"]

The environment is both Snow Leopard and linux running ruby 1.9.2 and Rails 3.0.5.

I found the ffi-locale on Github and that solves my problem as far as I can see.

It allows the following code:

FFILocale::setlocale FFILocale::LC_COLLATE, 'da_DK.UTF-8'
%w(Aarhus Aalborg Assens).sort { |a,b| FFILocale::strcoll(a, b) }

Which returns the correct result:

=> ["Assens", "Aalborg", "Aarhus"]

I haven't investigated performance yet but it calls out to native code so it ought to be faster that Ruby character replacement code...

Update
It is not perfect :( It does not work properly on Snow Leopard - it seems that the strcoll function is broken on OS X and have been for some time. It is annoying to me but the main platform for deployment is linux - where it works - so it is my currently preferred solution.

What's a Rails plugin, or Ruby gem, to automatically fix English grammar?

5 votes

Facebook just re-launched Comments, with a automatic grammar fixing feature.

What does the grammar filter do?

Adds punctuation (e.g. periods at the end of sentences)
Trims extra whitespace
Auto cases words (e.g. capitalize the first word of a sentence)
Expands slang words (e.g. plz becomes please)
Adds a space after punctuation (e.g. Hi,Cat would become Hi, Cat)
Fix common grammar mistakes (e.g. convert ‘dont' to ‘don’t’)

What is an equivalent plugin or gem?

I don't know of anything with those particular features.

However, you might look at Ruby LinkParser, which is a Ruby wrapper for the Link Grammar parser developed by academics and used by the Abiword project for grammar checking. (Note that "link" in Link Grammer parser doesn't refer to HTML links, but rather to a structure that described English syntax as a set of links between words).

Here's another interesting checker, written in Ruby, which is designed to check LaTex files for some of the problems you mention (plus others).