On May 8, 2005, at 11:24 AM, Raymond Brigleb wrote:> Hi everybody!
Hi Raymond!
> I''m trying to get a simple XML thingie my app is generating... it
> looks a little something like this (in my "feed" controller):
First, lets pull @website from the subdomain. We could try putting
it in the route, but that gets messy fast. This way, foo.mysite.com
will set @website to Website.find_by_name(''foo''):
class ApplicationController < ActionController::Base
before_filter :find_website_from_subdomain
private
# example.com => @website = nil
# foo.example.com => @website =
Website.find_by_name(''foo'')
# foo.bar.example.com => @website =
Website.find_by_name(''foo.bar'')
def find_website_from_subdomain
website_name = request.subdomains.join(''.'')
unless website_name.blank?
# Simple, but allows users to view other users'' websites.
# @website = Website.find_by_name(website_name)
# Assume login_user gives me the currently logged-in user.
@website = login_user.websites.find_first([''name=?'',
website_name])
# Augh, user is a baddie trying to access another user''s
website.
if @website.nil?
redirect_to :controller => ''home'', :action =>
''naughty_naughty''
end
end
end
end
Now let''s use @website in our category feed:
class FeedController < ApplicationController
def category
@category = @website.categories.find(params[:id])
render_without_layout
end
end
And munge the view to expect @category rather than @pages:
xml.category(:id => @category.id) do
for page in @category.pages
xml.page :id => page.id, :title => page.title
end
end
> My question: how can I render that XML to a file rather than
> showing it in my browser. My intent is actually to FTP that XML to
> another server, if that helps... maybe there''s a neat-o way to do
> that in one fell swoop, but I can''t find it... any help would be,
> as always, very appreciated...
Try a seperate export action that generates the feed and FTPs it to
the remote server. Start with a nice route:
# Example: export category 5 by sending a POST to /export/category/5
map.connect ''/export/:feed/:id, :controller =>
''feed'', :action =>
''export''
require ''tempfile''
require ''net/ftp''
class FeedController < ApplicationController
def export
case request.method
# Show export form.
when :get
# No setup necessary.
when :post
# Nab the feed contents from the other action.
feed = render_component(:action => params[:feed], :id => params
[:id])
# Write the feed to a tempfile and FTP it.
# Note: the tempfile is deleted at the end of the block.
Tempfile.open do |file|
file.write feed
# Assume ftp_host, ftp_username, ftp_password, and ftp_basedir.
Net::FTP.open(@website.ftp_host) do |ftp|
ftp.login @website.ftp_username, @website.ftp_password
# Switch to the appropriate export directory for this feed.
ftp.chdir File.join(@website.ftp_basedir, params[:feed])
# Send the file named as the feed id with an .xml suffix.
ftp.put file.path, "#{params[:id]}.xml"
end
end
# Return to the export form and let the user know all''s well.
flash[:notice] = "Exported #{params[:feed]} #{params[:id]} to #
{@website.ftp_host}"
redirect_to :action => ''export''
end
end
end
For bonus points, add timeouts, rescue Net::FTPError, or switch gears
and use Jamis Buck''s Net::SFTP. Better yet, factor the website
export machinery into its own class and pare your export action down
to a sweet 8 lines or so.
Enjoy,
jeremy