Showing posts with label Sinatra. Show all posts
Showing posts with label Sinatra. Show all posts

Thursday, 19 May 2011

Using virtual attributes in ruby model.to_xml

If you have virtual attributes that you want to include in your to_xml call then you can override the to_xml on the model and pass the virtual attributes as methods. For example

class ModelName < ActiveRecord::Base
has_one :model_name_2

# real attributes a, b
attr_accessor :c, :d
delegate e, :to => :model_name_2
end

Now an instance (mn) of type ModelName calling to_xml will output

mn.to_xml

115true

Now to override the to_xml to include attributes c, d and e.

class ModelName < ActiveRecord::Base
has_one :model_name_2

class ModelName < ActiveRecord::Base
has_one :model_name_2
# real attributes a, b
attr_accessor :c, :d
delegate e, :to => :model_name_2

def to_xml
super(:methods => [:c, :d, e])
end
end

Now when to_xml is called on the model c, d and e will also be included.

mn.to_xml

115trueAnExamplefrom another model

Rspec testing IP based authentication

Setting up a simple service in Sinatra with IP based authentication where localhost is in the whitelist of allowed IP. The problem was that all tests were run under local host, fortunately you can pass rack environment as parameters to the get request. Example test

it "should fail authentication" do
get '/services/order/43439', {}, 'REMOTE_ADDR' => '192.168.9.873'
last_response.status.should == 401
attributes = Hash.from_xml(last_response.body)
attributes["errors"]["error"].should == "You are not authorised"
end

Where 192.168.9.873 is not in the whitelist

Wednesday, 18 May 2011

Sinatra/ActiveRecord Delegate Method Missing Error

I was doing delegation through multiple models earlier

class Model1 < ActiveRecord::Base
#model relationships

delegate :name, :to => :model2, :prefix => true
end

class Model2 < ActiveRecord::Base
#model relationships

delegate :name, :to => :model3, :prefix => false
end

class Model3 < ActiveRecord::Base
#model relationships
#where we want to access the attribute
end

Sinatra was throwing an error unknown method 'name' for Model2. This is strange since I had already told it to delegate this method to Model3. The problem was that even setting the :prefix to false in Model2 was causing method missing to be thrown. To fix all that was required was to remove the middle prefix making Model2

class Model2 < ActiveRecord::Base
#model relationships

delegate :name, :to => :model3
end

This then fixed the problem. When :prefix is assigned true it will prepend the model name to the accessor, you can specify a different prefix though using a different symbol.

class Model1 < ActiveRecord::Base
#model relationships

delegate :name, :to => :model2, :prefix => :user
end

This will allow you to access the name attribute of Model3 through model1.user_name