Optimize a backend rails app - ruby-on-rails

I have a rails app which serves as a backend for Bootstrap based frontend. My application is fully Rest based. Which tools can I use to find the unused joins or queries from database in code? Also, any tools/gems that can help in finding the code that can be refactored?
There are gems like Bullet or Rack-mini-profiler that work if Rails app is used to render view also. But how do I use gems like those to optimize and tune my queries and code if only way to get a response is from rest client?

Depending on the configuration of Bullet, I believe by default Bullet logs all optimizable queries in (Rails.root/log/bullet.log), I guess the others have similar configurations/logs.
You could setup bullet for your test environment, since if you're shooting for a good coverage you'd most likely be testing all the AR methods in the first place.
Additional enhancers are New Relic and tools like Rubocop for some best practice.
You should check this out as well.

Related

Rails Webpacker or Vue-CLI?

I'm building a Single Page (Web) Application. I'm quite smitten by Rails v5.0, especially its built-in API capabilities.
In the past I've built JavaScript frontends using Vue.js, usually with the templates provided by the Vue-CLI project. This allows deployment of Vue component-based static sites basically anywhere. It's great.
Now, Rails 5.1 has some built-in Webpack and Yarn features which look pretty compelling too. I'm not sure how to proceed with my new application.
My questions:
What are the pros/cons of integrating Webpack and Vue into Rails itself, using the Webpacker extensions available in Rails v5.1? I
intend to deploy to Heroku.
On the other hand, what are the pros/cons of using the Rails API-only mode for the backend, and maintaning the Vue/Webpack-based
frontend in its own directory? I'd keep everything in the same
repository, deploy the backend via Heroku, and the frontend via a
static host like Netlify.
Which approach would have more cognitive overhead or technical complexity?
Over the past few days, I've been looking around, and I've not found much concise information on the web about this. People seem interested in the auto-reloading features of the Rails development environment, but I get that for free already with Vue-CLI.
As far as I can discern, these are reasons for keeping them separate:
Deployment of the frontend is pretty darn simple to anywhere.
The Webpacker mode for Rails is very new, and not many tutorials or guides exist yet, especially regarding integration testing. Keeping
things separate means that my existing testing apparatus should still
apply.
Here are some pros for integrating the two parts together:
The possibility of using static assets both for the frontend and possibly for server-generated pages in the future, should that be
necessary.
Buy-in to "the Rails way", with implied future maintenance by the Rails team.
the JS Frontend would not need to be hosted separately.
Don't need to worry about CORS (?)
What other concrete benefits exist for either approach?
When i started i went the webpacker way, somewhow because that's what it looked like it was "supposed" to be. As you say, very little guidance.
Webpacker (with it's reliance on the latest node) seems a moving target, making deployment and even development more complex. For what benefit i asked and got rid of it.
Now i use vue from the cdn. Benefits:
cached close to user
almost zero installation
easy to have dev/production versions
The i write app code into the rails templates. Using haml, and in fact ruby2js, but you can use javascript just fine. That's how i started, but i like ruby, and the ruby code is almost half the size than the generated js, but i'm getting off track.
So templates are your "vue annoted" rails templates.
Small code also goes into the rails template.
More code can be defined in the assets and referred to from the app.
Even components can be written into template using the x-template syntax.
And last but not least: Data can be transferred by to_json, directly into the templates. And in the same render. Much faster than an additional query. When to_json is not enough one can use rabl to get exactly what is needed.
I hope i made that clear. I am in the process of writing some vue-rails stuff up, as there is so little to be found. Look out here (and i'll comment when the post is ready)

What tools to use for a website with lots of "realtime" page updates (coming from a Rails background)?

We are planning to make a "large" website for I'd say 5000 up to many more users. We think of putting in lots of real time functionality, where data changes instantly propagate to all connected clients. New frameworks like Meteor and DerbyJS look really promising for this kind of stuff.
Now, I wonder if it is possible to do typical backend stuff like sending (bulk) emails, cleaning up the database, generating pdfs, etc. with those new frameworks. And in a way that is productive and doesn't suck. I also wonder how difficult it is to create complex forms with them. I got used to the convenient Rails view helpers and Ruby gems to handle those kind of things.
Meteor and DerbyJS are both quite new, so I do expect lots of functionality will be added in the near future. However, I also wonder if it might be a good idea to combine those frameworks with a "traditional" Rails app, that serves up certain complex pages which do not need realtime updates. And/or with a Rails or Sinatra app that provides an API to do the heavy backend processing. Those Rails apps could then access the same databases then the Meteor/DerbyJS app. Anyone thinks this is a good idea? Or rather not? Why?
It would be nice if anyone with sufficient experience with those new "single page app realtime" frameworks could comment on this. Where are they heading towards? Will they be able to handle "complete" web apps with authentication and backend processing? Will it be as productive/convenient to program with them as with Rails? Well, I guess no one can know that for sure yet ;-) Well, any thoughts, guesses and ideas are welcome!
For things like sending bulk emails and generating PDFs, Derby let's you simply use normal Node.js modules. npm now has over 10,000 packages, so there are packages for most things you might want to do on the server. Derby doesn't control your server, and it works on top of any normal Express server. You should probably stick with Node.js code as much as possible and not use Rails along with Derby. That is not to say that you can't send messages to a separate Rails app, but since you already have to have a Node.js app running to host Derby, you might as well use it for stuff like this.
To communicate with such server-side code, you can use Derby's model events. We are still exploring how this kind of code works and we don't have a lot of examples, but it is something that we will have a clear story around. We are building an app ourselves that communicates with an email server, so we should have some real experience with this pretty soon.
You can also just use a normal AJAX request or send a message over Socket.IO manually if you don't want to use the Derby model to do this kind of communication. You are free to make your own server-side only routes with Express along with your Derby app routes. We think it is nice to have this kind of flexibility in case there are any use cases that we didn't properly anticipate with the framework.
As far as creating forms goes, Derby has a very powerful templating system, and I am working on making it a lot better still. We are working on a new UI components feature that will make it possible to build libraries of self-contained UI widgets that can simply be dropped into a Derby app while still playing nicely with automatic view-model bindings and data syncing. Once this feature is completed, I think form component libraries will be written rather quickly.
We do expect to include all of the features needed for a normal app, much like Rails does. It won't look like Rails or work like Rails, but it will be similarly feature complete eventually.
For backend tasks (such as sending emails, cleaning up the database, generating pdfs) it's better to use resque or sidekiq
Now, I wonder if it is possible to do typical backend stuff like
sending (bulk) emails, cleaning up the database, generating pdfs, etc.
with those new frameworks. And in a way that is productive and doesn't
suck. I also wonder how difficult it is to create complex forms with
them. I got used to the convenient Rails view helpers and Ruby gems to
handle those kind of things.
Also, my question is not only about background jobs, but also about stuff one can might do during a request, like generating a pdf, or simply rendering complex views with rails helpers or code from gems. –
You're mixing metaphors here - a single page app is just a site where the content is loaded without doing a full page reload, be that a front end in pure js or you could use normal html and pjax.
The kind of things you are describing would be done in a background task regardless of the fornt-end framework you used. But +1 for sidekiq if you're using ruby.
As for notifying all the other users of things that have changed, you can look into using http://pusher.com or http://pubnub.com if you don't want to maintain a websocket server.

What's the benefit of using Sinatra instead of RoR if I'm only need a DB and an API

I need to build a web service, for a mobile game, to manage the states of multiplayer games. I need a database and an RESTful API to access it. I'm very familiar with Ruby On Rails and was thinking of using that since I can throw together the DB and API pretty quickly. However, since RoR is a framework for building web pages and I'm not actually building any web pages, it naturally seems like the wrong technology to use even though it would work. As such, I'm considering using Ruby on Sinatra, but I've never used it before and I'll have to kill some time learning it. For you Ruby gurus, is there an advantage to using Sinatra or a disadvantage to using RoR for what I'm trying to accomplish?
Thanks so much in advance for your wisdom!
You know Rails, you don't know Sinatra. Personally I prefer the latter for things like building APIs, but there's nothing stopping you from doing it in Rails, and there's nothing intrinsically wrong with it either. Unless you want to see this as a learning opportunity for getting into Sinatra, I'd say stick with Rails. Here's some links that might be useful btw:
Building APIs With Rails
Building a Platform API on Rails
It probably depends on your API. If you need more than just a bunch of routes then you will have to come up with your own solutions (authentication, ...).
If all you need is some RESTfulness without the added weight, Sinatra is great. All you need to know is what happens in what route and you're fine. See the Sinatra Readme which has all the information to get started.

What tech stack/platform to use for a project?

This is a bit of a weird meta-programming question, but I've realized that my new project doesn't need a full MVC framework, and being a rails guy, I'm not sure what to use now.
To give you a gist of the necessary functionality; this website will display static pages, but users will be able to log in and 'edit their current plans'. All purchasing and credit card editing is being handled by a recurring payment subscriber, I just need a page to edit their current plan. All of that will be done through (dynamic) XML API calls, so no database is necessary.
Should I stick with my typical rails/nginx stack, or is there something I could use that would lighten the load, since I don't need the Rails heft. I'm familiar with python and PHP but would prefer not to go that route. Is Sinatra a good choice here?
tl;dr: What's a good way to quickly serve mostly static pages, preferably in Ruby, with some pages requiring dynamic XML rendering?
If you want to stick with Ruby, Sinatra would be fine, as would Rails Metal.
If you're feeling a bit adventurous and want to get some useful experience with the technology that rails uses you could try building a Rack application. It's a pretty simple API to be able to respond to generic HTTP queries, and from there you can quickly build static file handling and XML processing. It's also considerably faster to start up and serve pages than rails.
http://github.com/cloudhead/toto is an example of a decent Rack based application.
If you know Rails, then why not just stick with it? That way you can use all authentication features, etc. that you're used to without having to learn another platform and incur the implementation risks that that includes. If the application ever grows beyond what's expected you're already on a solid base.

All I need is ActiveRecord and ActiveMailer, should I use Rails/Merb?

I have a small web application that is currently running on Sinatra. It only has two pages so I don't really need controllers or many views. I have included ActiveRecord to interact with a database and ActiveMailer to send and receive mail.
Would it be worth it to use Rails, or Merb on a project as small as this? I find myself adding features that are included in Rails. I haven't had any experience with Merb before so I don't really know if that would be a suitable option. But from what I hear Merb may be the way to go on a project that only needs a few components.
Thanks.
No need to switch to Rails if your already running on Sinatra for a small project. You can use ActiveRecord and ActiveMailer outside of Rails.
Merb is merging with Rails for Rails version 3.0. As part of this process, the core Rails architecture is going to be "merbified" so as to be more easily configured to only use the particular components you need.
There may going to be a point as your application grows that you find yourself reinventing features that already exists, in this case I would consider switching frameworks.
Personally, I use Rails even for quite small projects. It means I have a single framework and deployment environment for everything that I work on.
I use Sinatra often for stuff much bigger than what you describe. What features of Rails do you find you are needing to add? If it's just stuff like 5.hours.ago and stuff, you could always: a) pull that part of the code out of activesupport and paste it into a 'common'/similar file in your project or b) just require activesupport and use it's features.

Resources