XML feed into Rails object - ruby-on-rails

I'm doing some work with Adcourier. They send me an xml feed with some job data, i.e. job_title, job_description and so on.
I'd like to provide them with a url in my application, i.e. myapp:3000/job/inbox. When they send their feed to that URL, it takes the data and stores it in my database on a Job object that I already created.
What's the best way to structure this? I'm quite new to MVC and i'm not sure where something like this would fit.
How can I get an action to interpret the XML feed from an external source? I use Nokogiri to handle local XMl documents, but never ones from a feed.
I was thinking about using http://api.rubyonrails.org/classes/ActionDispatch/Request.html#method-i-raw_post to handle the post. Doest anyone any thoughts on this?

In your job controller add a action inbox which gets the correct parameter(s) from the post request and saves them (or whatever you need to do with it).
def inbox
data = Xml::ParseStuff(params[:data])
title = data[:title]
description = data[:description]
if Job.create(:title => title, :description => description)
render :string => "Thanks!"
else
render :string => "Data was not valid :("
end
end
Next set your routes.rb to send posts request for that URL to the correct location
resources :jobs do
collection do
post 'inbox'
end
end
Note I did just made up the xml parse stuff here, just google a bit to find out what would be the best solution/gem for parsing your request.

Related

Access old get parameters in URL after a post request

I have a form in RoR with a controller action that looks up a record via the get parameter.
def respond
if request.post?
# Submit logic here...
# cannot lookup this way to fill the form out again
# #current_message = Saved_message.find_by_id(params[:msg_id])
elsif request.get?
#current_message = Saved_message.find_by_id(params[:msg_id])
end
end
I can't use the params[:msg_id] to lookup the message again because it's a post request and I don't resend the get parameters. However, the get parameters remain in the url such as .../messages/respond?msg_id=2. I can get around this by passing in a hidden field with a different parameter name like <%= form.hidden_field :msg_id_2, value: params[:msg_id] %>. Then I can lookup the #current_message via the params[:msg_id_2]. However, I don't like this solution. Any advice to access the now inaccessible get parameter?
you should use RESTful routes so that you do not have to care about such issues.
since you are not posting much about the actual code or problem you are trying to solve, i can just assume what might be the issue here and how to solve it.

How to get videos from rss feed entries

I am trying to get videos(urls) from feed entry url.
I am using Feedjira and MetaInspector in my application to fetch and store articles along with images. Now I want to store videos of articles if any. Can anyone please tell me what could be the best possible ways to store videos from articles
Thank you.
I do this in my project to save all the url found from rss feeds
Source.all.each do |source|
feed = Feedjira::Feed.fetch_and_parse(source.url)
feed.entries.each do |entry|
unless Link.exists? url: entry.url
Link.create!(title: entry.title,
url: entry.url)
end
end
end
in my snippet, I only save the url and title, for videos you just need to add entry.video,
you can see all the entry tag from feed.entries object or from the rss given.
and If you want to add another attributes, ex: media:thumbnail you could add this code before calling fetch_and_parse but you need to call it once not everytime you call fetch_and_parse to avoid memory leak
Feedjira::Feed.add_common_feed_entry_element("media:thumbnail", :value => :url, :as => :pic)
then you could do entry.pic to get the thumbnail url

How to pass a param from one view to another in Ruby on Rails, using POST

I feel like this should be an easy thing to figure out, but I'm stumped.
I have a value in a Project's instance variable called ID. I want to pass that value to a new Photos page to associate each photo that is created with that specific project, but I don't want the Project's ID to show up in the visible query string.
I've tried using link_to and button_to, but (I suspect) since I'm using "resources :photos" in my routes, all of the requests that come to photo#new are being interpreted as GET instead of POST.
Helllllllllllllllp!
Thanks to anyone that can give me some insight, I'v been killing myself over this for the past hour or two already.
--Mark
The usual way to do this in Rails is to create a route that matches urls like this: /projects/4/photos/new. Doing something else is up to you, but Rails makes it really easy to do stuff like this. See more on routes in Rails 3.
Your entry in routes.rb should look something like this:
resources :projects do
resources :photos
end
Then in app/controllers/photos_controller.rb you'd have this for the "New Photo" form page:
def new
#project = Project.find_by_id(params[:project_id])
end
and this for the action that the form in app/views/photos/new.html.erb submits to:
def create
#project = Project.find_by_id(params[:project_id])
#photo = #project.photos.create(params[:photo])
end
Of course you'll want to have error handling and validation in here, but this is the gist of it. And remember, use GET for idempotent (non state-changing) actions (e.g. GET /projects/4/photos), POST for creating a new thing (e.g. POST /projects/4/photos), and PUT for updating an existing thing (e.g. PUT /projects/4/photos/8).

POSTing File Attachments over HTTP via JSON API

I have a model called Book, which has_many :photos (file attachments handled by paperclip).
I'm currently building a client which will communicate with my Rails app through JSON, using Paul Dix's Typhoeus gem, which uses libcurl.
POSTing a new Book object was easy enough. To create a new book record with the title "Hello There" I could do something as simple as this:
require 'rubygems'
require 'json'
require 'typhoeus'
class Remote
include Typhoeus
end
p Remote.post("http://localhost:3000/books.json",
{ :params =>
{ :book => { :title => "Hello There" }}})
My problems begin when I attempt to add the photos to this query. Simply POSTing the file attachments through the HTML form creates a query like this:
Parameters: {"commit"=>"Submit", "action"=>"create", "controller"=>"books", "book"=>{"title"=>"Hello There", "photo_attributes"=>[{"image"=>#<File:/var/folders/1V/1V8Kw+LEHUCKonqJ-dp3oE+++TI/-Tmp-/RackMultipart20090917-3026-i6d6b9-0>}]}}
And so my assumption is I'm looking to recreate the same query in the Remote.post call.
I'm thinking that I'm letting the syntax of the array of hashes within a hash get the best of me. I've been attempting to do variations of what I was expecting would work, which would be something like:
p Remote.post("http://localhost:3000/books.json",
{ :params =>
{ :book => { :title => "Hello There",
:photo_attributes => [{ :image => "/path/to/image/here" }] }}})
But this seems to concatenate into a string what I'm trying to make into a hash, and returns (no matter what I do in the :image => "" hash):
NoMethodError (undefined method `stringify_keys!' for "image/path/to/image/here":String):
But I also don't want to waste too much time figuring out what is wrong with my syntax here if this isn't going to work anyway, so I figured I'd come here.
My question is:
Am I on the right track? If I clear up this syntax to post an array of hashes instead of an oddly concatenated string, should that be enough to pass the images into the Book object?
Or am I approaching this wrong?
Actually, you can't post files over xhr, there a security precaution in javascript that prevents it from handling any files at all. The trick to get around this is to post the file to a hidden iframe, and the iframe does a regular post to the server, avoiding the full page refresh. The technique is detailed in several places, possibly try this one (they are using php, but the principle remains the same, and there is a lengthy discussion which is helpful):
Posting files to a hidden iframe

How do can you make redirect_to use a different HTTP request?

At the end of one of my controller actions I need to redirect to a page that only accepts put requests. I have been trying to figure out how to get redirect_to to use a put request but to no success.
Is this possible? Or is there another way to accomplish this?
I don't think you are able to do this, and I suspect that the limitation is part of HTTP itself.
When using redirect_to - the redirection happens as a "302 Moved" header unless otherwise specified in the parameters.
Having a look at the HTTP Spec itself doesn't reveal any way to change the type of request the browser makes via redirect.
HTTP Redirects:
This class of status code indicates
that further action needs to be taken
by the user agent in order to fulfill
the request. The action required MAY
be carried out by the user agent
without interaction with the user if
and only if the method used in the
second request is GET or HEAD.
I think you may need to use JavaScript to achieve this functionality, or perhaps rethink the flow of control in your application.
If the action is in the same controller as where you're trying to redirect from, simply call the action and render the template like so:
def show
index
render :action => "index"
end
If it's not, then I don't know how you do that.
Ok, so I found a solution to my problem. I found a very good write up on the situation here. My implementation looks like this:
private
def redirect_post(redirect_post_params)
controller_name = redirect_post_params[:controller]
controller = "#{controller_name.camelize}Controller".constantize
# Throw out existing params and merge the stored ones
request.parameters.reject! { true }
request.parameters.merge!(redirect_post_params)
controller.process(request, response)
if response.redirected_to
#performed_redirect = true
else
#performed_render = true
end
end
Then I called this method like this:
redirect_post :controller => 'registrations', :action => 'order', :_method => 'put', :authenticity_token => params[:authenticity_token]
So I was able to 'fake' a put request by making a post request (using redirect_post) and then assigning 'put' to a _method param. If you look at a normal put request all it is a post from a form with a _method param. So its a bit hackish but it gets the job done.
Also, you have to make sure that when you call redirect_post the values of your hash are strings otherwise errors will be thrown.
You could redirect to a different page that issues the put request from the client, using Javascript.

Resources