ACRCloud webapi in Rails - ruby-on-rails

I'm a newb hobbyist developer. Can I just throw this repo of their ACRCloud's ruby example code into a controller? I'd like to use an audio fingerprinting song recognition database as a name validation for songs users are uploading using paperclip. Not sure if it's possible, just starting to research it, any hints or suggestions would be appreciated.
Obviously I'd have to replace
file_name = ARGV[0]
etc, but I'm also wondering about the require 'openssl' etc

Definitely! But there are few points to be taken care of. That's a pure ruby script, when it comes to rails there are certain rules/best practices. One of which is thin controller and fat model..
You need to create a route/action in your app which will ask the app to execute this request with required params.
Write a method in your model which contains the code and call it from controller and pass the permitted params to it.
Instead of hardcoding your credentials in the model, make them environment variables.
Would suggest using Httparty gem wgich will reduce many lines of your code and you just need to pass headers, params, etc. as hash in the arguments.
Last, but not the least...if you notice..there's a puts in the end however, rails uses mvc and so you need to have a view for the controller action you created in step1. Return and save the response.body in the class variable like #response = res.body and you can play with the body depending on the response type.
Hope it helps..
P.S. I wish I could write few lines of code/optimise it for you but i m using my mobile right now. But I think this much information should be enough to convert that script to mvc rails structure..

Related

What's a good way to stub Contentful Model instances in feature specs?

(I think this question generalises to stubbing any extensively-pinged API, but I'm asking the question based on the code I'm actually working with)
We're using the Contentful Model extensively in our controllers and views including in our layouts. This means that in any feature test where we visit (say) the homepage, our controller action will include something like this:
class HomepageController < ApplicationController
def homepage
# ... other stuff
#homepage_content = Homepage.find ('contentful_entry_id')
end
end
... where Homepage is a subclass of ContentfulModel::Base, and #homepage_content will have various calls on it in the view (sometimes chained). In the footer there's a similar instance variable set and used repeatedly.
So for feature testing this is a pain. I've only come up with two options:
Stub every single call (dozens) on all Contentful model instances, and either stub method chains or ensure they return a suitable mock
or
Use a gem like VCR to store the Contentful responses for every feature spec
Both of these (at least the way I'm doing them) have pretty bad drawbacks:
1) leads to a bunch of test kruft that will have to be updated every time we add or remove a field from the relevant model;
2) means we generate a vcr yaml files for every feature test - and that we have to remember to clear the relevant yml file whenever we change an element of the test that would change the requests it sends
Am I missing a third option? Or is there some sensible way to do either of the above options without getting the main drawbacks?
I'm the maintainer of contentful_model.
We use VCR to stub API Calls, so that you can test with real data and avoid complicated test code.
Cheers

Shopify API calls not working in Rails background job

In my Rails controller action, I have a method that does a bunch of Shopify API calls. Things like:
ShopifyAPI::Product.all()
ShopifyAPI::Product.find(:all, params: {title: title})
ShopifyAPI::Product.create(title: title, body_html: description, images: images, tags: tags, product_type: product_type)
All of it does what I want...very neat.
The problem is that I'm going to be uploading a CSV and using this controller method. It's fine if I have like 8 line items, but very quickly it gets slow. So, I thought, let's move it to a background worker.
I'm using Redis/Resque to get everything going and using some dummy outputs (i.e. puts 'Hi there champ!') I've confirmed that the background worker is configured properly and executing when and where it should be. Neat.
So then I put bits and pieces of my controller action in and output that. That all works until I hit my Shopify API calls. I can call .new on about any object, but the when I try to .find, .all, or .create any valid object (which worked before I abstracted it to the background job), it sort of goes dead. Super descriptive! I've tried to output what's going on via logger and puts but I can't seem to generate much output of what's going on, but I have isolated it down to the Shopify API work. I thought that, even though I have an initializer that specifies my passwords, site, API keys, secrets, etc, I might need to reinitialize my Shopify session, as per their setup docs here. I either did it wrong, or that did solve the issue.
At this point I'm sure I'm just missing something in the docs, but I cannot find out how to make these necessary API calls from my background job. Any thoughts on what I might be doing obviously wrong that could solve this? Anyone dealt with anything similar?
Turns out this has to do with where the Shopify Engine was mounted. In my routes.rb I have the following (in addition to other routes; these are the two pertinent ones):
mount ShopifyApp::Engine, at: '/'
root to: 'products#index'
This is all fine and good, but sort of forces the context of your Shopify API calls to be made within the context of the products.rb index controller action...without some changes. 2 ways to do this, one obviously the more Railsy way to do it:
Option 1:
Include
session = ShopifyApp::SessionRepository.retrieve(1)
ShopifyAPI::Base.activate_session(session)
at the beginning of any file in which you want to make Shopify API calls. This sets the session (assuming you only have 1 store, by the way...this is using the retrieve method to retrieve store 1. Risky assumption), authenticate to the API, and everything in life is good.
Option 2:
Class inheritance for the win. Have all your controllers that are making API calls inherit from ShopifyApp::AuthenticatedController. This makes the initializer actually work, and that's it. This is (in retrospect) the clear and obvious way to go. Have an order controller? class OrdersController < ShopifyApp::AuthenticatedController and done: order = ShopifyAPI::Order.find(params[:id]) does exactly what you'd expect it to.

Generate XML Request Payload with Template in Rails

I'm working on a rails app that integrates with a 3rd party on the backend. To give a quick overview, a user will create an order in our web interface and that will persist a delayed job. So, the job runs outside of a web context and will send a request to this 3rd party. The 3rd party expects a POST with an XML payload in the request body.
I'm currently using Faraday to do the request. I have a class that looks something like this:
class FooRequest
def response
connection.post("/foo", xml)
end
private
def xml
xml = Builder::XmlMarkup.new
xml.root do
xml.foo "something something"
end
xml.target!
end
def connection
#connection ||= Faraday.new(url: "http://example.org")
end
end
The XML is actually bigger and more complex than that and so I don't want to build the xml in this class. I think having some sort of template is best. I'd either like to use Builder in a xml.builder file or just have raw XML in a erb file. Not sure which is best and how best to render a template in this context. I know that rails recently added the ability to render views outside of a controller context (https://medium.com/evil-martians/new-feature-in-rails-5-render-views-outside-of-actions-2fc1181e86a8#.s344qg5ue) but I feel like that feature wasn't built for this use case. I also know that there are other templating languages like Liquid and maybe that's a better fit.
Has anyone done this sort of thing in the past? Is there something I'm missing?
Also, if I do create a template file, should I put it in /app/views? It's not a view that my webapp would render, maybe I should have a /app/templates dir?
PS: Rails's to_xml method is not robust enough for what I want (I need tag attributes and I don't want to represent a deep complex XML tree with a ruby hash).
I've done a similar thing, the easiest way I found was to implement whatever XML classes I needed into a separated gem (you don't really have to do this you can just add the classes somewhere in the models folder, it made sense for my use case).
I used ROXML for this; after that you can simple call root.to_xml.to_s to render your string, see the examples on github, it's really straightforward.

Where to store editable content?

I am building a Rails app that is intended to be eventually used by non-technical people. It consists of a few pages with blocks of text and a special page with interactive canvas drawings.
I want to allow them to easily edit any piece of text contained in the application. What are the best ways to achieve that? Currently, text is written in the different views of the application, which does not allow them to edit it without having to connect via FTP or similar and search for the right file.
I am thinking of three solutions:
Store all blocks of text in the database. On each page, fetch the requires blocks and insert them before rendering. Build a page that lists all blocks in the database in editable areas with a save button.
Store all blocks of text in a json file. Create a model that can read the file and fetch the blocks required by the views. Build a page that lets you edit each block and save it in the file.
Create some kind of password-protected admin interface that fetches all file in the views directory, use regexp to find blocks of text and allow the users to edit each block and save.
From my point of view, all of my three solutions look pretty bad. It does not feel okay to do so many calls to the database? Store your entire website text in a file? Parse HTML with regexps?
What are the usual approaches used to solve this problem?
There's a great book out there: Crafting Rails 4 Applications. Here's the link to source code from the book. You will find example in templater folder. Basically, you will be able to create custom templates based on the request parameters (just like Rails does).
Update. Here's a couple of links:
Default views in Rails 3.0 with custom resolvers by José Valim (author of the book, by the way).
Implementing a Rails 3 View Resolver.
Also, here's 5 coins from me. Basically, it works like this. You need to define your own resolver and connect it to your ApplicationController (or any other controller you want):
class Resolver < ActionView::Resolver
# some code here
end
class ApplicationController < ActionController::Base
append_view_path Resolver.new
end
During the rendering process, Rails will ask your controller's resolvers to provide a template (it will go through each of them, until it finds template or until there won't be any resolvers left). In order to provide template, your resolver needs a find_templates method:
def def find_templates(name, prefix, partial, details)
# some processing here
end
So, based on this method parameters, you're going to provide some database records. But even if you have some kind of model already, Rails expects this method to return ActionView::Template instance. It can be initialized like this:
ActionView::Template.new(source, identifier, handler, details)
So, that's how your find_templates should look like:
def find_templates(name, prefix, partial, details)
template = DatabaseTemplate.find... # your custom model for DB templates
ActionView::Template.new... # initializing actual template
end
Both model and resolver in detail are presented in the book's source code (templater/3_final/app/models/sql_template.rb).
I have done that a couple times with awesome user satisfaction by using this:
http://jejacks0n.github.io/mercury/
There is also a Railscast available which gives you a good overview and step by step instructions:
http://railscasts.com/episodes/296-mercury-editor
Hope it helps. It looks good and is easy to use for end users.

Finding sets in Rails

I'm a Rails noob, but I'd like to use it as a backend for an Ember application with Ember Data. Unfortunately, I have some unknown unknowns.
The RESTAdapter documentation says:
Comments for a post can be loaded by post.get('comments'). The REST
adapter will send a GET request to /comments?ids[]=1&ids[]=2&ids[]=3.
It will generate similar urls if you use something like App.Post.find({title: "Some Title"}), in about the format you'd expect: /posts?title=Some+Title
Is there some option, or gem I can use to handle that sort of simple query, or do I have to go parse parameters in my controllers manually?
To clarify, I'm aware that I can tell my Rails controller to return a set like:
#comments = Comment.find(params[:ids])
respond_with(#comments)
But it seems like querying on ids or accessible attributes like that would be a common enough use case for REST APIs that something would be built in, or have a gem written to handle it.
Can anyone point me in the right direction?
Thanks.
This might be helpful in your case:
https://github.com/ernie/ransack/
Or
https://github.com/ernie/squeel

Resources