Key folders
app/config/db/public/lib/test/Asked in interviews
AskedExplain the Rails directory structure and purpose of key folderswhere runs no SQL until you use the records, so you can keep chaining.app/config/db/public/lib/test/Asked in interviews
AskedExplain the Rails directory structure and purpose of key foldersUser to its table, controller and keyusersUsersControlleruser_idTrapBusiness logic belongs in the model, not in the controller.
:name differs from "name"A symbol is immutable and stored once. Each string literal is a new, mutable object.TipAs hash keys, symbols share one object and compare faster.
development reloads code, test has its own database, production caches.RAILS_ENV=staging bin/rails credentials:editTipconfig/ overrides config/ for one environment.
TrapCommit credentials., but never config/, which decrypts it.
admin/user.rb to its constantAdmin::Userbin/rails zeitwerk:checkTipDevelopment reloads changed code. Production eager loads all of it at boot.
TrapInitializers must not use reloadable constants under app, because reloading replaces them.
Asked in interviews
AskedExplain the Rails autoloading mechanismbin/rails g model Userbin/rails g generator xrails plugin new e --mountableTipAn engine shares a feature across apps. You must version it.
Asked in interviews
AskedWhat are Rails generators and how do you create custom ones?bin/rails middlewareconfig.middleware.use XTipA middleware takes the next app in initialize, and its call(env) wraps @app.call(env).
Asked in interviews
AskedExplain the request/response cycle in Railsresources :postsbin/rails routesresources block inside another gives /users/:user_id/posts .index, new and createshallow: trueTipThe router uses the first match, in file order.
TrapAvoid nesting more than 1 level deep, because URLs and path helpers grow long fast.
before_action :find_postskip_before_action :authTrapIf a filter renders or redirects, Rails halts the request and the action never runs.
Asked in interviews
AskedWhat are before_action filters and how do they work?render :new, status: 422redirect_to @userrespond_to do |format|TipRails reads the format from the extension or Accept. An unlisted format answers 406.
TrapTurbo only shows a form response that redirects or carries an error status, so a failed save needs 422.
params.require(:user).permit(:name) params.expect(user: [:name])attr_accessibleTrapUnpermitted params raise Forbidden at the model. A missing require key returns 400.
Asked in interviews
AskedWhat are strong parameters and why are they important?Service.new(params).call extend ActiveSupport::Concern included doTipSkip a service for simple create and update actions.
TrapA concern that only splits one large model keeps it as large and hides its callbacks.
validates :email, presence: truevalidate :my_checkerrors.add(:x, "bad")Tipsave returns false on failure, and save! raises.
TrapParallel requests can both pass a uniqueness check, because it runs in Ruby. Add a unique index.
belongs_to :userhas_one :profilehas_many :poststhrough: :taggingshas_and_belongs_to_many :tagspolymorphic: trueTipbelongs_to checks that the parent exists, unless you pass optional: true.
TrapThe database can't enforce a polymorphic key. A renamed parent needs its stored _type values updated.
Tipthrow :abort halts the chain. An update runs the same chain with update.
TrapEverything up to after_save runs in the transaction. Send email from after_.
Asked in interviews
AskedExplain callbacks in ActiveRecord and their order of executiondelegate :name, to: :usernil targetprefix: trueallow_nil: trueextend ForwardableTipMonkey patching reopens a class to change it. A refinement applies only where you call using.
TrapA gem or a later Rails version can define the same method, and whichever loads last wins.
User.find(1)nil if noneUser.find_by(email: e)User.where(admin: true)Trapwhere returns an empty relation when nothing matches, never nil. find_by! raises.
Asked in interviews
AskedWhat's the difference betweenfind, find_by, and where?scope :live, -> { where(live: true) }User.pluck(:email) User.select(:id) TrapA scope whose body returns nil still returns all records, so a chain never breaks. A class method returns the nil.
User.includes(:posts) User.strict_loading TipLazy loading suits one record, or a page that may never read the association.
TrapOn a loaded association, use size. count always runs a SQL COUNT query.
preload(:posts)LEFT OUTER JOIN, to filtereager_load(:posts) includes(:posts)INNER JOIN, with no eager loadjoins(:posts).distinct TipFor a SQL string condition, references(:posts) forces the join.
Trapjoins loads only the users. Reading user.posts afterwards still runs one query per user.
relation.explain User.find_eachcounter_cache: trueTrapEach index slows writes to its table and takes storage, so add only the ones your queries use.
Asked in interviews
AskedHow do you optimize database queries in Rails?bin/rails db:migratebin/rails db:rollbackTipdb/schema.rb is the snapshot that builds a fresh database.
Trapchange reverses itself only for reversible commands. Raw SQL needs up and down methods.
Asked in interviews
AskedExplain database migrations in Railsalgorithm: :concurrentlyself.ignored_columns TipThe strong_ gem catches unsafe steps in development.
TrapSet a short lock timeout. A blocked migration then fails fast instead of making every query wait behind it.
Asked in interviews
AskedHow do you run schema migrations without downtime?User.transaction dolock_versionFOR UPDATEUser.lock.find(1) TipOptimistic suits rare form conflicts. Pessimistic suits short, busy updates like balances.
TrapUse update! inside a transaction. update only returns false, so the block carries on.
pool: 5checkout_timeout: 5TrapTotal connections are the pool size times the process count, and must stay under the database's own limit.
Asked in interviews
AskedExplain database connection pooling in Railsconnected_to(shard: :one)TrapShards rule out joins and transactions across them. Rails doesn't choose the shard for you.
Asked in interviews
AskedWhat are the benefits and implementation of database sharding in Rails?where(name: name)where("name = ?", name)authenticity_token csrf_meta_tagsTipRails doesn't check GET requests, so they must never change data.
TrapString interpolation brings SQL injection back, in a where string or in find_by_sql.
:cookie_store:cache_storehas_secure_password user&.authenticate(pw)rails g authenticationdeviseTrapCall reset_session at sign-in. It stops session fixation, where an attacker plants a known session ID.
config.force_ssl = truebin/brakemanTipconfig. holds X-Frame-Options and the other defaults.
TrapNever call html_safe or raw on user data. Those two turn off the escaping views do for you.
rate_limit to: 10, within: 3.minutesrack-attackTrapKeep the counters in a store every server shares. Otherwise the real limit multiplies.
Asked in interviews
AskedHow do you implement rate limiting in Rails?rails new app --apistatus: :createdActiveModel::Serializer jbuilderjsonapi-serializerTrapList fields explicitly, so a new column never leaks into a response.
/api/v1/usersAcceptTrapAdditive changes ship in the current version. Only a breaking change, like a removed field, needs a new one.
Asked in interviews
AskedHow do you implement API versioning in Rails?JWT.decodeTrapA JWT stays valid until it expires. Keep its lifetime short, and pair it with a refresh token.
MyJob.perform_later(id) :solid_queue:sidekiqretry_on NetworkErrordiscard_on ActiveRecord::RecordNotFound Tipretry_on defaults to a 3 second wait and 5 attempts. Make a job idempotent, meaning safe to run twice.
TrapThe result isn't ready when the response goes out, so show a pending state or notify the user later.
:solid_cache_store cache @product doRails.cache.fetch(key) TipA fragment goes stale when its record's updated_at changes. touch: true on belongs_to gives Russian doll caching.
Trap:memory_store gives each process its own copy, so several servers need a shared store.
Asked in interviews
AskedWhat is the Rails cache store, and what are the available options?stream_from "chat_1"ActionCable.server.broadcast("chat_1", data)solid_cableTrapThe async adapter is for development and tests only, not for several app servers.
Asked in interviews
AskedWhat is ActionCable and how does it work?turbo_frame_tagturbo_stream.append data-actionTipTurbo Drive swaps in the new page's <body> on links and forms, and the server keeps rendering HTML.
Asked in interviews
AskedWhat are Turbo and Stimulus, and how do they work with Rails?pin "application"PropshaftTipA fingerprint puts a digest of the content in the file name, so browsers can cache the file for a long time.
TrapImport maps can't use JSX or TypeScript, which need transpiling. Use jsbundling-rails for those.
Asked in interviews
AskedExplain the Rails asset pipeline and its benefitshas_one_attached :avatardirect_upload: trueTrapActive Storage doesn't limit file type or size, so validate both before you accept an upload.
Asked in interviews
AskedHow do you handle file uploads in Rails?I18n.t("users.welcome") I18n.with_locale(locale) TrapAssigning I18n.locale directly can leak into later requests on the same thread.
Asked in interviews
AskedHow do you implement internationalization (i18n) in Rails?Minitestrspec-railsusers(:john)create(:user)TrapEach factory create costs a database insert, so a large suite slows down.
allow(user).to receive(:admin?).and_return(true) expect(mailer).to receive(:send_email) get users_url, as: :jsonassert_response :createdTrapA test that checks every call is brittle. It breaks when the internals change, even when the behavior is still correct.
rails c --sandboxrails c -e productionrails dbconsoledebuggerTipStart from the development log. It shows each request's params, its SQL and the full backtrace.
bin/rails assets:precompilekamal deployTipRun job workers next to the web processes, and monitor errors and queues.
TrapRun migrations before the new code takes traffic, and keep the old code working with the new schema.
Asked in interviews
AskedWhat are the key considerations for deploying Rails applications?Nothing matches. Try a shorter word, or clear the search.
With Pro, you can:
Already have Pro? Sign in