Showing posts with label Ruby on Rails. Show all posts
Showing posts with label Ruby on Rails. Show all posts

Tuesday, January 5, 2016

Ruby on Rails Delegate

12:07 AM Posted by Unknown No comments
Delegation is a quite common practice in Ruby projects, if you consider proxies, mixins and composition as the ingredient of the Delegation Pattern.
The Delegation Design Pattern is a technique where an object exposes certain behavior but it actually delegates responsibility for implementing that behavior to an associated object.
When using Rails and the cool associations feature, it can be tempting to chain method calls like this:
product.provider.name  
provider.address.city
company.building.city
These lines violate the Law of Demeter. To fix it, we should change them to be :
product.provider_name
provider.address_city #or provider.city 
company.city
This way, it’s much cleaner and we don’t break the law anymore. But to do that, we need to add a bunch of methods to our models :
  class Product < ActiveRecord::Base
    belongs_to :provider

    def provider_name
      provider.name
    end

    # More methods to access the provider's attributes
  end

  class Provider < ActiveRecord::Base
    has_many :products

    # Has a name attribute
  end
You get the idea ! The models will grow out of control if we define methods for each attribute like this. But Rails has a solution : Delegate.
  class Product < ActiveRecord::Base
    belongs_to :provider

    delegate :name, to: :provider, prefix: true
  end

  class Provider < ActiveRecord::Base
    has_many :products

    # Has a name attribute
  end
Note the use of the prefix key. It allows us to use product.provider_name instead of just product.name since a product would probably have its own name.
Delegate is a really powerful feature that let you clean up your models. Let’s see another example.
If we have a Company that belongs to a Building, we could do :
class Company < ActiveRecord::Base
  belongs_to :building

  delegate :street, :city, :country, to: :building, allow_nil: true
end

class Building < ActiveRecord::Base
  has_many :companies

  attr_accessible :street, :city, :country
end
Now, we don’t break the law of Demeter anymore since we can access the street directly from the company object. Plus, less BS inside our models ðŸ˜‰ Note how we added allow_nil to the delegate. With this little addition, if the company does not have any building associated, we will just get nil when calling street and no exception!
If you never used the delegate method, it’s time to add it to your toolbox !
You can get more information about delegate in the documentation.

Thursday, November 26, 2015

How to create a valid RSS feed in Rails

6:28 PM Posted by Unknown 1 comment

Step 1

Create a new method in the posts controller.
app/controllers/blog_articles_controller.rb
class PostsController < ApplicationController

  ...

  def feed
    @posts = Post.all.order('created_at DESC').limit(20)
    respond_to do |format|
      format.rss { render :layout => false }
    end
  end

end

Step 2

Add a "view" for the feed.

Create the file
app/views/posts/feed.rss.builder
xml.instruct!
 
xml.rss :version => '2.0', 'xmlns:atom' => 'http://www.w3.org/2005/Atom' do
 
  xml.channel do
 
    xml.title 'Feed title'
    xml.description 'Feed description'
    xml.link root_url
    xml.language 'en'
    xml.tag! 'atom:link', :rel => 'self', :type => 'application/rss+xml', :href => feed_url
 
    for post in @posts
      xml.item do
        xml.title post.title
        xml.link post_url(post)
        xml.pubDate(post.created_at.rfc2822)
        xml.guid post_url(post)
        xml.description post.description
      end
    end
 
  end
 
end

Step 3

Add a route to /feed in the router file.

Edit
config/routes.rb

Add
get 'feed' => 'posts#feed'

Step 4

Add the following entry in the head section of your site template.

Edit
views/layouts/application.html.erb

Add a line like
<link href="https://www.your_website.com/feed?format=rss" rel="alternate" title="Your website RSS Feed" type="application/rss+xml"></link>
Then you can check Feed Validator for Atom and RSS here:  http://feedvalidator.org