I was wondering if there was a "proper" way to use RoR's MVC for doing all CRUD actions through something like rest_client. I won't have access to the DB but rather rest requests to do all CRUD actions.
Is there any way to define a model that contains all of the json data that would be returned on a get and put that into a model that can use Model.Save, Model.Create etc like a regular RoR application?
Would creating new methods def save, def create inside the ApplicationController work for this or not?
Edit: rest_client isn't required, just the ability to send json in post, get, delete and put with basic auth at the same time.
Edit 2: The only other idea I had was to use Active Model but those don't have save, delete etc methods. Would creating those that somehow tie into the ActionController::Base for wiring do this or not?
take a look at activeresource http://api.rubyonrails.org/classes/ActiveResource/Base.html
Related
I'm new to rails, I'm trying to figure out if rails have a request context where I can store variables and access them across the context of the request? I'm using rails 4.2.11.
I've tried to have a before filter in
class ApplicationController < ActionController::Base
before_action :set_request_context
def set_request_context
Thread.current[:request_context] = {:correlation_id => "some_unique_id"}
end
end
And then I'm accessing this variable else where in code. I'm sure this is not the right way because the application runs on ngnix and it may not guarantee that a request would be served by a single thread throughout.
When a request is processed within the method of the mapped controller a new object of a class is instantiated which needs access to this request_context.
class CreditCardPaymentsController < ApplicationController
def new
#paypage_id=PaypageIdRequest.new(:merchant_id => merchant_id)
end
end
Within the methods of PaypageIdRequest class I need to access the correlation_id I've set in :request_context.
Please note that I cannot send the variable to PaypageIdRequest class at the time of initialisation because there are so many places I'll have to send this variable and it would be bad practice to send it at all places considering Aspect Oriented Programming.
In Rails (and Rack applications in general) you have env which is a hash like object that contains the request object. env is used by middleware like Warden to inject themselves into your application.
However this is not a global. It is available in the routes, the controller and in views but not in models which are not request aware, neither is it available on whatever else you add to the MVC model like service objects or decorators unless you pass it.
If you want it to be available in your PaypageIdRequest class you need to use constuctor or method injection or make whatever you are saving a global.
Yes, Rails offers this functionality through it's CurrentAttributes API.
https://api.rubyonrails.org/classes/ActiveSupport/CurrentAttributes.html
I have the most basic of questions, but the more I think about it, the more complex it gets.
I've been using rails and it follows the MVC paradigm in that db and api calls are abstracted through calls generated through the controller. This seems way too heavy for what I want.
1) I want a simple (basic) web server that sits in front of my datastore. (The contents of which happen to be stored in a directory structure that follows: /LOCATIONS/LOCATION/PRESENTERS/PRESENTER/YEAR/MN/)
2) I want to be able to host json files within that directory structure and GET them as needed.
3) I want to be able to PUT/POST append to those json files.
Seems like all I'd need is nginx with my datastore as a doc root and index.html files at critical places within the structure (e.g. site.com/Locations/index.html , site.com/locations/SF/presenters/solomon/index.html)?
How would I begin to solve this problem, (without the use of controllers of coarse)?
MVC Frameworks
without the use of controllers
You must be aware that there are many more frameworks than Rails out there, so when you ask about using a system to "sit in front of your datastore", you're really looking for different frameworks to handle requests, of which there are many.
The problem you have is how do you keep data consistency, whilst ensuring you can handle the relevant API requests (through JSON). The answer is to look at how the systems you're examining work.
I can only really vouch for Rails (it's the only framework I've got production apps for) -
--
Rails
Creating an API in Rails is so simple - I don't know why you'd think about doing anything else
Using the MVC principle might seem bloated to you, but the security, structure and extensibility it provides is unmatched.
Here is how to create an API in Rails:
#config/routes.rb
namespace :api do
resources :controller, only: [:update, :create] #-> only PUT / POST
end
#app/controllers/api/your_controller.rb
class API::YourController < ApplicationController
respond_to :json
def update
# handle PUT request
end
def create
# handle POST request
end
end
#app/models/model.rb
Class Model < ActiveRecord::Base
end
This is all you need - you'll be able to access domain.com/api/controller.json POST to create data, and domain.com/api/controller/4.json PUT to update it :)
I'm writing my first mobile API an I can't find the best way to validate params, entities etc.
Now I do somethig like this before_filter :verify_adding, :only => :add and verify every param and entity in this verify methods. It doesn't look like elegant solution.
Please, suggest the best way to do such verifications
It's not the Rails way of validating input data.
Mostly you build an object using params and call the valid? function.
Because validation is a cross cutting concern which means that it will happen in different layers of your application, so it will be a good practice to put it somewhere so that you'd be able to call it somewhere else.
If your objects are ActiveRecord objects then the best place and way of validation is adding validation rules to your domain object which is an ActiveRecord derived object.
If not you can add ActiveModel modules to your domain object and use validation rules just like a regular rails app.
I need to pass a parameter from one method in a controller to another.
From my understanding I have to pass the parameters as a GET exposing it in the url string.
What is the best way to encrypt the data so no one can see what is actually getting passed in the string? Also, is there a way to pass it via POST or is my original understanding correct?
I haven't used RoR, but in the web world, this problem is solved with sessions. Using sessions you can store the parameters on the server and avoid sending sensitive data with GET or POST (both are insecure).
The Ruby on Rails Security Guide looks like a great read related to this.
I suggest you abstract your code into lib/ so that you don't have to call additional methods. Instead of making a new HTTP request, just put the code in a central place and call it from there.
class MyController < ApplicationController
def index
MyLibrary::Thing.do_stuff
end
def show
MyLibrary::Thing.do_stuff
end
end
# lib/my_library/thing.rb
module MyLibrary
module Thing
def self.do_stuff
# do stuff!
end
end
end
That way you can access the same code in multiple actions, without doing extra HTTP requests.
I'm using the BaseWithoutTable plugin to extend ActiveRecord. This allows me to create models without underlying tables (I'm getting data from a webservice). I would like my web application to remain restful, however i'm stumped on how to do that without relations.
To be more concrete, let's say I have a book model and an author model and I get both resources from a web service. I would like to access book resources like /authors/1/books.
It seems there could be two routes I could choose. First, hack the relations (belongs_to, has_many) so that I can define my own without the need for foreign keys. Second, I could possibly build custom routes and controller methods that allow me to access the previous url.
If anyone has any thoughts on how to do this I would much appreciate it.
Thanks and let me know if you need more info.
For the url given you could do the something like the following.
/authors/1/books
class Books < ApplicationController
before :find_author
def show
#books = Books.get_from_web_service_for_author(#author)
end
def find_author
#author = params[:author_id]
end
end
You would need to define the method for accessing your webservice and also have a nested resource defined in your routes.