Set Site/User Fields in Activeresource

Is it thread safe to set Active Resource HTTP authentication on a per-user basis?

Monkey patch the host, user and password methods of ActiveResource::Base class:

class ActiveResource::Base
# store the attribute value in a thread local variable
class << self
%w(host user password).each do |attr|

define_method(attr) do
Thread.current["active_resource.#{attr}"]
end

define_method("#{attr}=") do |val|
Thread.current["active_resource.#{attr}"] = val
end
end
end
end

Now set the credentials in every request

class ApplicationController < ActionController::Base

around_filter :set_api_credentials

private

# set the credentials in every request
def set_api_credentials
ActiveResource::Base.host,
ActiveResource::Base.user,
ActiveResource::Base.password = current_user_credentials
yield
ensure
ActiveResource::Base.host =
ActiveResource::Base.user =
ActiveResource::Base.password = nil
end

DEFAULT_HOST, DEFAULT_USER, DEFAULT_PASSWORD= [
"http://www.foo.com", "user1", "user78102" ]

def current_user_credentials
current_user.present? ?
[ current_user.host, current_user.login, current_user.password] :
[ DEFAULT_HOST, DEFAULT_USER, DEFAULT_PASSWORD]
end

end

Rails ActiveResource with custom REST collection schema?

ActiveResource by default has very strong expectations concerning format of data returned by the API, but you can provide your own format for scenarios like this.

Any Ruby object implementing a few expected methods can be used as a format. ActiveResource itself implements formats as modules, so we will stick to this convention.

Being a lazy man, I will reuse the standard JsonFormat implementation and only override method decode:

module CustomJsonFormat
include ActiveResource::Formats::JsonFormat

extend self

def decode(json)
ActiveSupport::JSON.decode(json)['data']
end
end

Now we just tell the ActiveResource subclass to use it:

class BaseModel < ActiveResource::Base
self.format = CustomJsonFormat

# ... set self.site, self.headers etc.
end

Rails ActiveResource Associations

ActiveResource does not support associations. But it doen't prevent you from setting/getting complex data to/from a ActiveResource object. Here is how I would implement it:

Server side model

class Customer < ActiveRecord::Base
has_and_belongs_to_many :groups
accepts_nested_attributes_for :groups
end

class Group < ActiveRecord::Base
has_and_belongs_to_many :customers
accepts_nested_attributes_for :customers
end

Server side GroupsController

def show
@group = Group.find(params[:id])
respond_to do |format|
format.xml { render :xml => @group.to_xml(:include => :customers) }
end
end

Client side model

class Customer < ActiveResource::Base
end

class Group < ActiveResource::Base
end

Client side GroupsController

def edit
@group = Group.find(params[:id])
end

def update
@group = Group.find(params[:id])
if @group.load(params[:group]).save
else
end
end

Client View: Accessing customer from Group object

# access customers using attributes method. 
@group.customers.each do |customer|
# access customer fields.
end

Client side: Setting customer to Group object

group.attributes['customers'] ||= [] # Initialize customer array.
group.customers << Customer.build


Related Topics



Leave a reply



Submit