Archive for the Rails Category

a DRYer way to include modules

Posted in Rails on April 16, 2008 by Adam

You may have noticed in the previous post that we used the RMobio ads module merely by doing “require rmobio/ads” inside our controller class. This is terser than and less repetitive (in the spirit of Don’t Repeat Yourself) than doing a require followed by doing an include inside the module.

The code inside the module to allow this is

if MOBIO_CONFIG['ad_network']
  adlib="rmobio/ads/" + MOBIO_CONFIG['ad_network']
else
  adlib='rmobio/ads/' + 'no_network'
end
require adlib
eval("include " + adlib.camelize)

What this does is build up the specific class for the ad_network that is configured in the generic RMobio configuration file (RMobio.yml). If no ad network is configured, we still want to have calls to getAd and getAdByPage not fail. So there is a module called no_network.rb with those calls stubbed out.

We then do the require of whatever ad library is chosen. Finally we generate the code dynamically (using “eval”) to do the include of the module name (using the handy camelize function to get the module name from the filename). This generic technique of dynamically determining the right module to include can make your code a briefer and terser. We use it in the RMobio gem and I’m hoping it catches on wider in the Ruby community.

mobile advertising and the RMobio gem

Posted in mobile platforms, Rails on April 15, 2008 by Adam

We posted our RMobio gem for mobile Rails development on RubyForge about a month ago. I’ll be doing a series of blog posts describing how to use the various goodies inside it over the next few weeks.

The first one that I’d like to discuss is the “ads module”. This lets you easily add mobile advertising to your Rails apps without being familiar with the syntax for the API of each particular ad network. The networks that we support include: Google’s Mobile AdSense, AdMobs, mKhoj (an India-based mobile advertising network) and Smaato (an ad aggregator which serves up mobile ads from many other ad networks).

You will need to work with one or more of these ad networks to get a “publisher ID” before using our ads module in your Rails apps. But you will not need to learn any of their APIs. You’ll simply embed calls to either “getAd” (which takes a keywords argument) or “getAdByPage” (which assumes that the ad network “scrapes” your page to determine appropriate content) in your controller methods. Then just use the @ad variable inside your views. The specific ad network used is configured by setting the ad_network: variable in the rmobio.yml file used to configure all rmobio gem capabilities (the specific instructions appear below).

This whole approach makes it very easy to both start monetizing your applications with ad networks and also switch it easily later without making code changes.

Steps to Add Advertising to Your Apps

Follow the specific steps below to add the ads module to your apps:

  1. In environment.rb, add the following two lines to the bottom of the file (we want to load the configuration statically):
    require 'rmobio/config_manager'
    
  2. Edit the file rmobio.yml in the config directory (creating it if necessary) and add the ad_network property in the appropriate section (development:, test:, or production:). For example the following sets the ad_network to ad_sense in the development: instance.
    (in file config/rmobio.yml)
    development:
      ad_network: ad_sense
      ad_client: pub-0061196910475770  # use your own publisher ID here or the money will go to us!
    

    Valid values are: ad_sense, ad_mobs,m_khoj, and smaato.

  3. Embed the ad module in your controller. Specifically add “require mobio/ads” to the inside of your controller. Note that your ads module does some “tricks” to not have you have to do the “include” as well. We’ll describe this technique for making “requires” and “includes” DRYer in a later post. For now here’s an example of how to use it:
    class HomeScreenController <ApplicationController
      require 'rmobio/ads'  # note no need for include here
    
  4. Call ad retrieval functions from your controller methods. The function “getAd(keywords,adClient)” takes a set of keywords separated by spaces. It also takes your publisher ID. For example the call below will invoke Google’s Mobile AdSense (if the ad_network is set to that value in rmobio.yml) for ads related to the keywords “India” and “cricket”. You can also call “getAdByPage(adClient)”
       def index
         getAd("India cricket",MOBIO_CONFIG['ad_client'])
       end
    
  5. Use the ad variable in your view. The getAd method populates an instance variable called @ad. You can that use that variable in your view. For example:
        <h3>Your cool content
    
      ... the rest of the page...
      <%if @ad%>
      <%=@ad%>
      <%end%>
    

switching to WordPress

Posted in Rails on January 8, 2008 by Adam

As much as I would love to stay on Rails-based blogging software, I’ve been experiencing a bunch of strange Mephisto bugs recently.  And the project seems to not really be actively maintained.  So I’m switching over to WordPress.  There aren’t many good options for getting all of the content over, so the comments are lost here.

model oh model, where is my model?

Posted in Rails on February 9, 2007 by Adam
One of the strengths of Rails and ActiveRecord is that it makes it easy to build your models. You Don’t Repeat Yourself, with your model attributes being derived directly from your database tables. Then all you have in your model definition itself is a discussion of its relationship to other models, relationship to tables and

There are problems introduced by this power however. When writing your application, where is your model definition? Your attributes are generally all in your table definitions. Your models relationship to other models is in your model definition file. Your validations are often in your model, unless your database is performing some form of validation (a practice that is generally encouraged outside the scope of Rails). So they are usually in both places! Plus there’s a good chance in your Rails application that you have introduced at least one or two views to handle things that Rails needs (such as the need for a single column primary key). So now there’s a third place for your model attributes definition.

Rails introduces another way of handling database definition and versioning: rake migration scripts. These are very powerful ways to version and maintain database schemas and data in a product neutral way. But they also spread the definition of “what is the model” out even further. I talk to Rails developers who say “I never look at my database administration tool – I just incrementally edit my Rake migrations”. The problem is that distributes the model definition out even further! It is spread amongst multiple rake migrate scripts.

Many developers used to programming with other tools and environments are also accustomed to some form of graphical frontend to define and manage their database tables. This can be at the “physical level” of tables or at a more conceptual level of entities and relationship (with tools such as ERWin or Visio). Such environments not only ease understanding and ease of manipulation and modify database (and model) relationships but they are also much better at concentrating the model definition into one place.

So here’s my suggestion: An incredibly useful improvement to the Rails app development toolset would be a graphical “model and rake migration designer” frontend. Probably an Eclipse plugin that plays nicely with RadRails (part of RadRails in the future?).

This frontend would allow you to define models, graphically draw relationships between models choosing from amongst the Rails palette of possible model relationships, and generate rake migration scripts from model attribute definitions. It would generate increment rake migrations when model changes were made. It would also allow you to set validations on attributes and models that would be reflected in the model definitions themselves. It would generate migration scripts for join tables when called for by as has_and_belongs_to_many relationship. There are a lot of other features I’d like to see in this tool, but I’ll leave off for now. No, I’m not considering building this. But I and many other Rails developers I know would be delighted by having this tool to use.

Rails, REST and SOAP web services

Posted in Rails, software development on February 3, 2007 by Adam
I’ve spent a lot of my career in the web services world (before it was even called web services). So a lot of my colleagues often ask me “you like Rails?! how is that possible, the Rails community hates SOAP-based web services?”. I’ve often wondered about this myself. More specifically I’ve wondered at the seemingly religious antipathy of the Rails community (including the illustrious DHH himself) to the “WS-Deathstar”.So (primarily for the people who are confused by a web services’ zealots embrace of Rails) here’s my take on the matter: REST is great for many problems and applications. The first class support that DHH is providing for REST in the Rails core is very useful. I love the scaffold_resource generator and what it provides (as I’ve mentioned earlier here). I also like the approach to providing it: the idea of single controllers that respond to different clients (HTML, REST, and others) with different content. I do have reservations about the need to put wordy respond_to clauses in each controller action (I’ve proposed what I think is a simpler way here). Anyway, automatic support for REST is a good thing. REST is a great way to build simple point to point distributed app to app connectivity. And I agree that, for someone who wants to be aware of the innards of the code they are working with that it is simpler. I also agree that there are scenarios where a REST interface just makes it easier for multiple arbitrary clients on more diverse platforms and languages (there is perhaps stil a small chance that it may be difficult to integrate with a client SOAP stack on a device, but there’s basically no chance that it will be hard to invoke a REST interface from another platform).

But does that mean that SOAP is bad? In the simple app to app connectivity scenario my opinion is that it basically doesn’t matter. In the vast majority of languages and platforms the work of consuming a SOAP-based web service is just as easy as consuming a REST service. But I agree that there’s little tangible advantage to using SOAP if all you ever need is a distributed method call.

The value of the SOAPbased WS-Deathstar is when more complex connectivity is required: multihop message routing, guaranteed delivery, publish-subscribe one-to-many integration, more advanced security in the plumbing than https (the latter probably only necessary when you’re routing messages). If this is never going to be necessary (probably true for the typical consumer-facing website), then the whole SOAP vs. REST debate is moot. And going with the default easier path of REST doesn’t hurt one whit. For more advanced distributed connectivity problems (endemic to many “enterprise applications” that are seemingly anathema to the Rails community), robust SOAP stack with extensive WS-Deathstar support would be useful for developers building complex connectivity. And yes I mean a whole bunch of those nasty evil WS-* specs, including those not yet widely implemented. My top requests include WS-Addressing, WS-Eventing, and full WS-Security. Doing these would also obviate the need to provide other APIs for such such services as publish/subscribe message routing. Due to Ruby’s stunning productivity advantages I think any and all of these would be trivial to implement. I remember implementing a very early WS-Eventing client prototype in C# in about a page of code. It would be much easier in Ruby (if there’s demand for it, I’d consider rewriting it, if only to demonstrate that a seemingly complex spec can in fact be made easy to use).

Are the WS-* overly complex? Yes, I think many of them are. There are plenty of “design by committee” artifacts in there. For the most part such unnecessary complexity can be hidden from the programmer using them. A good API with reasonable default behavior (convention over configuration) covers a thousand design sins. And the layered nature means that you can just pick and choose what facilities help you. Embracing the Deathstar specs would make Ruby a more powerful tool for a wider set of applications. The availability of Rails plugins (or just Ruby libraries) for these capabilities would make it more likely that Ruby gets used for a wider variety of programming tasks which can only help to grow and advance the Ruby and Rails community.

consuming web services from your Rails app

Posted in Rails on February 2, 2007 by Adam
Despite the fact that SOAP-based web services seem to be considered politically incorrect by the Rails community, it is amazingly easy to expose web services from Rails. Ironically enough, it can be a little tricky to consume web services from Rails. Several of my colleagues have asked me to post this. This is mostly due to the strange web services client implementation in Rails (Action Web Services’ client). Essentially, you should just use the native Ruby web services client capability (SOAP::WSDLDriverFactory).Specifically, if you use the guidelines below it should be easier.

  • Don’t try to use the Action Web Services client. It only works with AWS servers.
  • Don’t use WSDL2Ruby.rb. Its buggy and not complete.
  • DO use the native Ruby SOAP services such as in the following code (the example points to a free sample Trivia web service)require ‘soap/wsdlDriver’ triviaEndpoint=”http://mobquiz.com/question/api”; triviaWsdl=wsendpoint+”?wsdl”service=SOAP::WSDLDriverFactory.new(smswsdl).create_rpc_driver question=service.askQuestion(‘Entertainment’) puts question.question

Rails database guidelines

Posted in Rails on January 30, 2007 by Adam
These are some guidelines on building databases that you will use with your Ruby on Rails applications. I have seen many of these elsewhere in scattered places, though I’m not sure that I agree with all the other takes on these issues. My intention is to both list good practices for building new schemata and how to handle inheriting legacy structure which diverge from these practices. Anyway here goes:

Create a Primary Key Column

It is a reasonable restriction to insist that tables have single columns for primary keys. If you’ve inherited a poorly designed, then just create a view onto it with such a column. Unlike the claims of many anti-Rails rants, the column does not need to be called id Using

set_primary_key your-other-primary-key-column

works just fine. But if you’re creating a new database, why not call the column id?

Foreign Key Columns

If you’re designing a new database you should follow the convention of naming the foreign_key column as othertablename_id.

If your existing table doesn’t have this please use a view.

Join Tables

Join tables should be named with the convention of firstModelnamePlural_secondModelnamePlural. The columns in the join table should use the convention just mentioned of joining back to the model name tables with columns named otherTableName_id.

Has Many Through Tables

If you are going to build a :has_many :through relationship, the :through model probably has its own attributes. Otherwise you would have done :has_and_belongs_to_many. Remember to give that model table its own :id column.

Parent Reference Columns

If you are using a model with :acts_as_tree the column which refers to the parent entities. You can override this with the :foreign_key option on :acts_as_tree

Pluralized Table Names

Its better practice if you’re creating a new database schema to use pluralized names. But if you’ve inherited a database that doesn’t follow these practices, you can enter the following in your config/environment.rb file.

ActiveRecord::Base.pluralize_table_names = false

Overriding Table Names

More generally, if you just don’t want to use the same name or plural of the same name as your model for your table name. Or if you’re inheriting a database schema, and you want to use a different name for your model than is reflected in your database, use the set_table_name option in your ActiveRecord model definition.

class YourModel &lt; ActiveRecord::Base
  set_table_name "some_table_name_different_than_model_name" 
end

Use Created_At and Updated_At Columns

If you create columns with these names, Rails will put the date and time of record creation in them for you. Be sure to leave the fields as allowing NULLs. For clarity you should avoid using other columns that have a similar purpose. For example, don’t use a column called “creation_time” that you put values in yourself.

There are also additional column names of created_on and updated_on that will be filled in with the dates only of record creation and modification times. I would tend to stick with created_at and modified_at flavors.

Avoid “Magic Columns” Unintentionally

Besides the columns mentioned there are several others that you could unwittingly use that will cause you problems. Don’t ever use these column names in your tables unless you know about and mean to use their special behavior.

created_at              
created_on             
updated_at
updated_on
lock_version
type
#{table_name}_count
lft
rgt
position
id                      
parent_id               
method
quote