module Api
module V1
class PostsController < BaseController
before_action :authenticate_user!
def create
post = current_user.posts.build(post_params)
if post.save
render json: post, status: :created
else
render json: { errors: post.errors }, status: :unprocessable_entity
end
end
def update
post = current_user.posts.find(params[:id])
if post.update(post_params)
render json: post, status: :ok
else
render json: { errors: post.errors }, status: :unprocessable_entity
end
end
private
def post_params
params.require(:post).permit(:title, :body, :published_at, tags: [])
end
end
end
end
Strong parameters prevent mass assignment vulnerabilities by explicitly whitelisting which attributes can be set via user input. Without this protection, attackers could modify sensitive fields like admin or account_balance by including them in request payloads. I define private *_params methods in controllers that specify exactly which parameters are permitted for each action. Nested attributes require nested permit calls, which can get verbose but ensures nothing slips through. For APIs, I often see developers disable strong parameters entirely, which is dangerous—instead, I keep them enabled and use schemas (like dry-validation or JSON Schema) as an additional validation layer. Strong parameters are the first line of defense against unauthorized data modification.
Related snips
class CommentsController < ApplicationController
before_action :set_post
def create
@comment = @post.comments.build(comment_params)
System test: asserting Turbo Stream responses
class Post < ApplicationRecord
belongs_to :author, class_name: 'User'
has_many :comments, dependent: :destroy
scope :published, -> { where.not(published_at: nil).where('published_at <= ?', Time.current) }
scope :draft, -> { where(published_at: nil) }
ActiveRecord scopes for reusable query logic
payload = {
sub: user.id,
iss: 'https://auth.example.com',
aud: 'codesnips-api',
exp: 15.minutes.from_now.to_i,
iat: Time.now.to_i,
JWT issuance and verification without common footguns
module Api
module V1
class UsersController < BaseController
def show
user = User.includes(:profile).find(params[:id])
ETags for conditional requests and caching
class PostsController < ApplicationController
def index
@posts = Post.includes(:author)
.order(created_at: :desc)
.page(params[:page])
.per(10)
Turbo Frames: infinite scroll with lazy-loading frame
require "csv"
class PeopleCsvStream
include Enumerable
HEADERS = %w[id full_name email signed_up_at plan].freeze
Resilient CSV Export as a Streamed Response
Share this code
Here's the card — post it anywhere.