Every now and then, I stumble upon some post that raises interesting questions worth to be answered or commented upon, hence the *"My Answers to..." series.*
This one in particular is worth the name since they're explicitly relating to interview questions, which were formulated in a very interesting blog post follow-up by Sohan back in 2010.
Rack is a web server interface for Ruby frameworks. It provides a common interface and middleware to provide a common HTTP-to-application-server communication layer regardless of the backend server implementation. It's a very minimal interface, specifying that a Rack application is any Ruby object responding to a
#call method, this method gets passed an environment (ENV) of HTTP-specific data coming from the web server in the form of a Hash-like interface, and it expects the method to return a server status code, headers, and response body.
Despite the fact of some implementation issues (like invoking
call..., a problem which Aaron Patterson has described in the past), the simple interface was a welcomed addition to the world of Ruby web development, as you can expect your Rack applications to run on the majority of Ruby web application servers untouched.
Through this minimal interface Rack ensures a protocol between web and application servers, releasing the latter from having to deal with straight HTTP "semantics" as it provides enough information for the request/response lifecycle. One of the main benefits of Rack is its stacked middleware approach, which are like interceptors that get before, between or after a request/response, manipulate or inspect it, totally transparent from the application code.
Examples of Rack-compatible application servers are wide, and the most common examples are Thin, Unicorn, Passenger and Puma. Examples of useful middleware are JSONP, Profiler, Cache, and of course the ones that Rails applications include by default.
Ensure to reset the session ID on every successful login attempt, as a result the attacker won't be able to use a fixed session ID after the user logs in since the server will issue a new session ID for every single valid login, effectively replacing the old one. It's strictly necessary as well to analyze and purge Cross Site Scripting (XSS) vulnerabilities from the application, as this effectively removes the exploitation vector entirely as the attacker won't be able to inject the session ID replacement into the user's browser. Both counter-measures are not exclusive and need to be implemented on any Rails application.
From the GitHub repository at https://github.com/rails/rails. In the interest of contributing to Rails source the best way to get started appears to be populating a Vagrant virtual machine made specifically for Rails development, which can be found at https://github.com/rails/rails-dev-box.
There are many ways and patterns to get this accomplished. Since we're talking about a Rails project, the particular way of doing it in Rails which doesn't relate to other patterns is through the use of Rails Engines, where you can reuse models, views and controllers across different apps.
I haven't extracted any plugins to date.
I have never had the need to use a so-called pre-initializer. However, in my understanding the pre-initializer code (which is any code you place at
RAILS_ROOT/config/preinitializer.rb) would be executed before any of the Rails components get loaded (such as ActionPack, ActiveRecord, etc). Initializers on the other hand, run their code after the framework and any plugins or gems your application uses gets loaded, there can be multiple of them, and they're stored under the
I don't remember how to use this, but as with any configurable part of Rails, you would create or copy your Log4r configuration into your Rails project (in case it requires one), then switch the logger in your application config (after you've required the specific Ruby libraries),
config.logger being the variable that needs to be touched.
Through well-established conventions, log tagging, and instrumentation-based logging.
Most-likely through the use of a message queue such a RabbitMQ.
This is not an exact science, you need to graph, map, get usage stats, isolate, and scope. Oink is a tool that can help you to log memory-related usage patterns to your production log. NewRelic has tools to display memory usage. The operating system itself would provide some great low-level tools such as
mini-profiler, is a Rack middleware that shows you response time as well as some inner processing times within the Rails stack. Now, in the real world I use NewRelic. You can also go the
ruby-prof way, patch your Ruby version for Garbage Collection statistics,
perftools.rb or my recently preferred way a mixture which starts with
A lambda is a closure, it's a specified block of code that gets defined inline and preserves the surrounding scope of where it was defined.
A proc is something like a lambda which is a little bit looser. Procs are close to blocks where lambdas are close to methods. Both are Ruby blocks of code which retain the enclosing scope, and despite a few differences when it comes to argument checking and what happens when you return from such of block they're pretty much the same. I've learned by force to always use
#call on such blocks. In Ruby-code the question would be "where don't you use them".
If my understanding is correct major ORMs in Rails are using
ActiveModel::Callbacks behavior which defines that every callback method which returns false would halt the execution of any other callbacks scheduled to run later, so effectively if you return false on a
before_destroy would prevent the operation. I also think if the method code raises an exception it will have the same effect.
You would extract them to a module which either defines the methods to be run on callbacks, or registers the callbacks itself after inclusion (such as when using
I'm not sure about an architecture, but the trick here is to never put the files on public-accessible locations (such as the public directory inside your Rails application), instead you put them in some private location outside of your web server's root, then make a controller which would run any kind of validation as filters (actions in Rails 4 parlance), and if all succeed then will serve the file directly through the use of the
If the question is how to serve the static files within Rails (which is off by default on production, obviously, as no application server should serve static files by itself, and most are not designed for that), you would set
config.serve_static_assets = true in your application config. If you're using a cookie-less domain or a CDN and you want to specify where your assets are served from (so you can properly link using the Rails URL helpers) then you would set config.asset_host in your application configuration to the address of your server.
You should be using Russian-Doll caching everywhere when it doesn't introduces more problems than speed.
Since Rails 4, only fragment caching. Action caching (per controller action but allowing filters) and Page caching (skips the Rails stack entirely) are available through separate gems.
Rails is a framework built because of the dynamic features of Ruby, so I don't even know where to start. I think the most fundamental one is that through the use of blocks, and clever meta-programming (such as defining dynamic finders, or invoking a list of callbacks, or avoiding similar method definitions), and the everywhere-openess of Ruby, have allowed them to built a web domain specific language that just feels right.
I have no idea. I used to do that on Java, not anymore, soap4r I suppose.
You out-band it, which basically means you move it out of the request/response lifecycle by using some sort of background processor or messaging solution.
I honestly don't remember. I feel something in the stone age of when Rack wasn't along and Ruby app servers were starting that would allow you to run multiple instances of your application through different process. Most app servers today support this forking model and can let you run as many "workers" (instances of your application) as you configure them to, the only exception I can remember now might be Puma on threading mode.
I don't think so.
Through the use of the i18n library bundled with Rails (or an alternative), and the use of helpers in views, model translations and of course locale files.
rails g generator <generator_name>, if you want to use a generator to build a generator .
Yes, who hasn't had a
Commentable in their lifetime?
ActiveRecord::Base to include your module, most likely one that includes
ActiveSupport::Concern and has a nested
ClassMethods module which is the one that defines the class method in question.
Rails 3 is old-school, I'll talk about Rails 4: Strong parameters instead of mass-assignment,
ActionController::Live and streaming, concerns, but my favorite is Russian-Doll Caching.
For starters, you should be pre-computing on the fly and doing a lot of caching, and definitely not doing the report at the web layer. However, apparently the preferred way in the SQL world would be employing what's called "views", some of which you can map to models. In the NoSQL world (my favorite BTW) you'll most-likely do various kind of map-reduce operations to get the desired results.