I managed to get the create action working by using HTTParty and
writing the methods myself. This isn't ideal, though - I'd much
rather use ActiveResource as it is what I am using everywhere else. I
seems if I send Sinatra the parameters as "param=var" it works (this
is what I'm constructing manually with HTTParty), but the xml hashes
Rails is constructing Sinatra isn't interpreting correctly. This is
what I have at the moment. I don't have an update action yet.
>> The Sinatra Server
# index
get '/urls.xml' do
protected!
Url.all.to_xml
end
# show
get '/urls/:id.xml' do
protected!
Url.first(:id => params[:id]).to_xml
end
#post
post '/urls.xml' do
protected!
content_type :xml
uri = URI::parse(params[:target])
raise "Invalid URL" unless uri.kind_of? URI::HTTP or uri.kind_of?
URI::HTTPS
#@url = Url.first(:target => uri.to_s) || Url.create_url({:target =>
uri.to_s}, 6)
@url = Url.create_url({:target => uri.to_s, :user_id => params
[:user_id]}, 6)
@url.to_xml
end
delete '/urls/:id.xml' do
protected!
@url = Url.first(:id => params[:id])
@url.destroy
end
>> The Rails Client
- LINKS_CONTROLLER
# GET /urls
# GET /urls.xml
def index
@links = Link.find(:all)
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => @links }
end
end
# GET /urls/1
# GET /urls/1.xml
def show
@link = Link.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => @link }
end
end
# GET /urls/new
# GET /urls/new.xml
def new
#@address = Url.new
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => @link }
end
end
# GET /urls/1/edit
def edit
@link = Link.find(params[:id])
end
# POST /urls
# POST /urls.xml
def create
@link = LinkService.new('user','pass').post(params[:target],
current_user.id)
redirect_to '/links/' + @link["url"]["id"]
>> NOTE - I kept getting a bizarre HTTParty related URL rewrite error when I tried to use Rails named paths here (links_path works, but link_path(@link["url"]["id"]) does not - even manually putting in an ID or using the whole object), so I ended up having to construct the URL explicitly.
end
# DELETE /urls/1
# DELETE /urls/1.xml
def destroy
@link = Link.find(params[:id])
@link.destroy
respond_to do |format|
format.html { redirect_to(links_url) }
format.xml { head :ok }
end
end
- LINK.RB (ActiveResource)
class Link < ActiveResource::Base
self.site = "http://user:pass@site/"
self.element_name = "url"
end
- LINK_SERVICE.RB (HTTParty)
class LinkService
include HTTParty
base_uri 'site'
def initialize(u, p)
@auth = {:username => u, :password => p}
end
def post(url, user_id)
options = { :query => {:target => url, :user_id =>
user_id}, :basic_auth => @auth }
self.class.post('/urls.xml', options)
end
end
If it would be helpful to see more of the code, I can probably provide
more of the site, but that's all the relevant parts. As you can see,
using HTTParty and ActiveResource is really an inelegant solution and
I really prefer the simplicity of AR. Any thoughts?