Category: Ruby On Rails

  • Old rails project with gem install errors :/

    At work I am going to work on an older rails project… Like many other Rails projects, this one can only run on older versions of ruby. Hence I install rbenv and tried my luck.

    My luck failed though and I had some issues installing “thin” gem which is used with “mailcatcher” gem.

    Eventually I found this post, which helped my Mac compile the thin gem file with native extensions:

    https://meta.discourse.org/t/mailcatcher-gem-installation-issue-on-macos-catalina-and-its-solution/168606

    Long story short:
    install the gem separately with custom compiler flags and run bundler install again.

    rbenv exec gem install thin -v 1.5.1 -- --with-cflags="-Wno-error=implicit-function-declaration"

    At last i can run rbenv exec bundler install and the rest of the installation can begin.

  • IE + iframe + cookies

    After spending lots of hours building a system for a client, using Ruby on Rails, everything was deployed and worked perfect… until IE came along that is.

    The customer had iframed the project into their current website, and since the user had to sign in to the new project using an iframe, IE began to give all kinds of errors.
    The direct link worked like a charm, but IE seems to want more!

    I stumpled upon an answer on stackoverflow – where else? (link to stackoverflow answer)
    It simply states, that if you want to use cookies in iframes, using IE, you need to add a P3P header.
    And it worked!

    Rails howto

    To do this in Rails, simply open up “application_controller.rb” and add a new filter:
    before_filter :set_pthreep

    The code for the filter is added in the private section of the application_controller.rb file:
    def set_pthreep
    response.headers['P3P']= 'CP="Potato"'
    end

    And that’s all there is to it.

  • Using rails and respond_to to include nested data

    I want to display data from a nested table in my XML output using respond_to. I searched google a bit and it seems :include was the way to go. However I had some problems getting this to work properly.

    I have two models (customer and user) that are linked together. When I fetch the data for a single user, I want my xml output to include the customer data.

    The Customer model:

    class Customer < ActiveRecord::Base
      has_many :users
    end
    

    The User model:

    class User < ActiveRecord::Base
      belongs_to :customer
    end
    

    In my UserController I use the respond_to method to respond to html and xml data.
    The show action is as follows:

    # Shows the seleted user
    def show
      @user = User.find(params[:id])
      
      respond_to do |format|
        format.html
        format.xml { render :xml => @user) }
      end
    end
    

    Calling the show action on the user controller as xml should yield something like:

    <user>
      ...
      <customer>
        ...
      </customer>
    </user>
    

    But the customer data is not included.
    This puzzled me a bit.

    Searching a bit on google got me the following answer:

    # Shows the seleted user
    def show
      @user = User.find(params[:id])
      
      respond_to do |format|
        format.html
        format.xml { render :xml => @user.to_xml(:include => @user.customer) }
      end
    end
    

    source: http://rubydoc.info/docs/rails/3.0.0/ActionController/MimeResponds

    (I also tried fetching the customer out separately, that didn’t work either)

    This gave me the following error:

    undefined method `macro' for nil:NilClass
    

    The solution

    After a lot more searching I found out, that you shouldn’t pass an object, but a symbol. The name of the symbol is the data block you want to show, so in my case it was :customer

    The code to fix it was:

    # Shows the seleted user
    def show
      @user = User.find(params[:id])
      
      respond_to do |format|
        format.html
        format.xml { render :xml => @user.to_xml(:include => :customer) }
      end
    end
    

    The data for the customer now returned as well.

    Need more data?

    If you need data from several tables, just use an array of symbols instead.

    # Shows the seleted user
    def show
      @user = User.find(params[:id])
      
      respond_to do |format|
        format.html
        format.xml { render :xml => @user.to_xml(:include => [:customer, :table2, :table3]) }
      end
    end
    

    Hope you can use this tip.