Backbone.js on Rails - Access data in Rails outside of the Backbone model - ruby-on-rails-3

I have a Backbone.js application with RoR for the backend.
The typical backbone.js setup is it gets the data from the table, and updates/saves data to that same table. However, my backbone model is made of a universal list of vendors, and I want a user to be able to "select" a vendor, which would dump into a DIFFERENT table, called user_selected_vendors.
I don't even know how to set this up in backbone. Any ideas?

Its hard to give specific advice without seeing some code examples.
In general though, you should think of your Rails backend as providing JSON service endpoints for your Backbone code to talk with. When your Rails app receives requests from the Backbone front end, you can do whatever is necessary with the request data. You are not limited to providing JSON endpoints which directly map to your database tables.
Also, based on the name of your user_selected_vendors table, it seems like you are not taking advantage of the ActiveRecord associations. What you may really want is something along the lines of adding has_many :vendors association to your User model. See: http://guides.rubyonrails.org/association_basics.html#the-has_many-association

Related

Guide to designing complex API that works in a RESTful way?

I have tried out the RESTful API concept and found out that its a great mindset for building resources APIs. For example, adding comment to post would be
POST /posts/{id}/comments
However, there are some cases, correct me if I am wrong, that the expected APIs can not really be model as a simple CRUD
For example, adding product to the system requires adding picture, adding multiple tags specify its category?
How do I do this the restful way?
1.) Do I force the API user to follow after multiple API calls?
POST /pictures -- add picture
GET /categories -- get selected category
POST /tags -- add tags
POST /products -- input picture, category, tags ids as JSON fields
2.) Do I use nested object which automatically do find all subresources?
POST /products -- input nested JSON array with picture/category/tags object field
In this case, all subresources will be existing resources instead of some (picture, tags) that should be posted.
Also, what would happen if adding picture succeed internally but adding tags failed?
3.) Do I just do a casual API? How does this fit with REST? Doesn't this break the RESTful idea?
POST /add_products
Is there any guide to deal with complex API for RESTful APIs?
Thank you.
In my opinion, one of the biggest misconception people have about REST is that internal models (tables in db or document in mongo) and REST resources must be same. REST resources can be a real model or it can be an abstract entity as well which might not exist in db.
So in this case, your url with POST i.e. POST /products request is perfectly alright as far as REST is concerned. And advice from my personal experience - One doesn't needs to be too dogmatic about url as long as basic principles of REST are conserved such as
Use right HTTP verbs
Use right status codes
Cacheable architecture
Unique indentification of resource by url
Hypermedia (if you can go that far)

How to implement HATEOAS in Rails

I've started with ActiveResource, but quickly hit the wall. Could not get ActiveResource to work when overriding to_json and to_xml on the underlying model. Plus, could not make resource representation inject links into the generated xml document. Oh btw, I'm using Rails 3.2.1.
I did a bit of research and found out about its gem. Tried it, for some reason didn't work for me. So my question is:
If I have one resource (say books) hosted in one web site (something like http://books.org), and another resource (say students, http://students.org), hosted in another web site, how can I get books to represent themselves to a student in their full HATEOS glory?
I was able to get the book resource to represent itself to the asking student as an XML document. I did that by using vanilla Rails ActiveResource in the students site. I've created Books resource that inherits from ActiveResource::Base. Then I specified the self.site and self.element_name, after which I was able to perform some rudimentary ActiveRecord-like queries against the remote books site. The only thing that worked for me was Book.all and Book.find(1). Even that was not satisfactory because the representation contained all database columns, and I wanted to at least remove some of those, which turned out not to be possible.
Now that I've abandoned that approach, I am wondering if there is a working example in Rails where it is possible to build a more sophisticated representation of a resource (i.e. books) that will contain links that will drive the application state transfer? I find it simply unbelievable that such a simple requirement seems so devilishly difficult to implement in Rails. All I'm trying to do is create a representation of a resource that will include some links which will guide the consumer on its discovery of what that resource is capable of. I'm mostly interested in implementing the workflow, which is a layered, peeling-the-onion type of conversational process of discovery.
In Rails, you'd need to change the way the serialization of your object happens if you're looking to do this in JSON. (You need to override the way Rails gives back representations of resources.) The most common gem for doing that would be: https://github.com/rails-api/active_model_serializers
If you don't want to use AMS or want to return HTML, consider following this presenter pattern: http://blog.steveklabnik.com/posts/2012-01-06-implementing-hateoas-with-presenters

Difference between Active Model, Active Record and Active Resource

Is there anyone who can help me by defining the exact difference between Active Model, Active Record and Active Resource. I have done enough googling in order to find the exact difference, but didn't get anything concrete which can tell the exact difference between them. Right now they all look same to me. So please give me the appropriate answer with some concrete points.
Rails 3 is designed with modularity in mind. Each module has its own purpose and functionality.
ActiveModel: This component was created in Rails 3. They took all the model related parts that did not have a database requirement of Rails 2 ActiveRecord and moved it into ActiveModel. So ActiveModel includes things like validations. More information: http://www.rubyinside.com/rails-3-0s-activemodel-how-to-give-ruby-classes-some-activerecord-magic-2937.html
ActiveRecord: This is the component that associates a class to the database. This will give the class functionality such as methods that make it easy to pull records from the database (An example is the find method).
ActiveResource: Similar to ActiveRecord. However, instead of being backed by a database, an ActiveResource object is backed by another application through a web service API. More information: http://ofps.oreilly.com/titles/9780596521424/activeresource_id59243.html
(Couldn't figure out about ActiveBase... where did you hear it from?)
What I understand:
ActiveModel + Database Support = ActiveRecord
ActiveModel via WebService API = ActiveResource
ActiveModel https://github.com/rails/rails/tree/master/activemodel
Think of a super model who is in constant need of validation.
ActiveModel can be used for many things, but mostly recognized for adding validation support to models / db records.
ActiveRecord https://github.com/rails/rails/tree/master/activerecord
Think record as in table record.
Sets up a mapping between a new class and an existing table in a database.
In the context of an app, these classes are commonly referred to as models. Models can also be connected to other models; this is done by defining associations.
class Firm < ActiveRecord::Base
has_many :clients
has_one :account
belongs_to :conglomerate
end
In the background, rails uses ActiveRecord for schema management and defining properties for your records, acting as an ORM (object relational mapper):
"ORM: An object that wraps a row in a database table or view, encapsulates
the database access, and adds domain logic on that data."
A schema outlines the properties for a record.
ActiveResource https://github.com/rails/activeresource
Think resource like the R in URL or of the resource routing that powers many rails backends.
Allows you to do things like Create, Retrieve, Update, or Destroy (CRUD) via HTTP.
tyler = Person.find(1)
When a request is made to a resource route, a RESTful request maps itself its corresponding HTTP verbs and their database interactions
GET => Person.find(1)
POST => Person.new(:name => 'Tyler', :favorite_page => 'stackoverflow')
PUT => tyler.save
DELETE => tyler.destroy

Rails 3 forms and models

I'm coming from Asp.Net MVC world and I'm confused how to approach Rails 3 forms from model perspective.
In Asp.Net MVC it is a bad practice to bind to business model forms in templates. The proper approach is to create a class for each form, create properties which are only needed in form and attach validation attributes to them. Then in code check for ModelState.IsValid and assign values from form model to business model. This leads to separation of concepts and also prevents properties hijacking (when hackers might post additional values together with proper values and change business model properties in his cruel way).
From all tutorials and books I've read there is no seperation of this concept in Rails world - you put validation in your business model and you bind your model to the form in the template.
Is it the right approach in Rails 3 and I should follow it? Or I should follow Asp .Net MVC approach and create a separate model with validation just for forms?
In rails, updates of models generally happen via mass-assignment. For example, a form posts a ton of attributes to your update action, your update action calls:
Model.update_attributes(params[:model])
and all the values in the passed hash are updated on the model. The problem then is what happens if a hacker adds
params[:model][:users_attributes][:email] = 'hacker#example.com'`
and updates the model's associated user's email address?
In Asp.Net MVC it seems like you simply don't allow this in the form template and the value can never get to your models, but in rails this is not the way things are done (correct me if I am misunderstanding Asp.Net MVC). In Rails, everything in a model (by default) can be mass-assigned, and so your fear is warranted.
In the link I supplied, you can see "For a normal user account, for example, you only want login and password to be editable by a user. It should not be possible to change the status attribute through mass assignment."
class User < ActiveRecord::Base
attr_accessible :login, :password
end
This means any other properties must be set manually and the object saved, thus preventing the same type of property-hijacking that Asp.Net's form templates protect against. In Rails, anything that should be mass-assignable should be in your attr_accessible and then ActiveRecord is the gatekeeper. No matter how your forms are written or what a hacker does to their HTML, those attributes can only be updated explicitly by your code, not by Rails' behind-the-scenes stuff.

How to connect Social Media Streams (Twitter, Instagram) in Rails

I am doing my first baby steps with Rails (version 3) now. I'd like to create a simple app catching data from the twitter/instagram/ API. Thankfully there are already gems doing the heavy lifting with connecting to the services, providing the data. Now I wonder what the best-practice is to add this functionality to Rails correctly.
My feeling is the best way is to create a new non-DB Model for each service I want to include and create some scopes, which I will then use in the controller. The scope definition includes the functional code, instantiating and using the twitter/instagram gems to get the web service's data.
Is this model/scope approach right or did I miss something?
In future I might need to cache all the fetched data to handle common API request limitations. Is there any good approach for this?
I'd appreciate your thoughts or examples/resources on this topic.
I think in this situation a standard class would be ok e.g.
class TwitterImport
def get_tweets
# Download tweets
...
# Create tweets
Tweet.create(.....
end
end
I created something similar recently. I created a folder called scripts in my app directory and stuck a class in there called import.rb. Because this file lives within the app directory it automatically has access to the Rails goodness i.e. existing Models etc.
I then set it up as a rails runner script, you run it via teh console from your app's root directory:
rails runner -e development TwitterImport.get_tweets