• Stars
    star
    80
  • Rank 390,306 (Top 8 %)
  • Language
    Ruby
  • License
    MIT License
  • Created over 1 year ago
  • Updated 11 days ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Pattern matching for Rails applications

rails-pattern_matching

Build Status Gem

This gem provides the pattern matching interface for ActionController::Parameters, ActiveModel::AttributeMethods, ActiveRecord::Base, and ActiveRecord::Relation.

That means it allows you to write code using pattern matching within your Rails applications like the following examples:

# app/models/post.rb
class Post < ApplicationRecord
  has_many :comments
end

# app/models/comment.rb
class Comment < ApplicationRecord
  belongs_to :post
end

# app/controllers/posts_controller.rb
class PostsController < ApplicationController
  def update
    @post = Post.find(params[:id])

    case params.require(:post).permit(:title, :body, :published)
    in { published: true } if !can_publish?(@post, current_user)
      # Here we are matching against a single parameter with a guard clause.
      # This allows us to express both the value check and the authorization
      # check in a single line.
      render :edit, alert: "You are not authorized to publish this post"
    in permitted if @post.update(permitted)
      # Here we are grabbing the entire set of parameters and then using it to
      # update the post. If the update succeeds, this branch will be taken.
      redirect_to @post, notice: "Post was successfully updated"
    else
      # Here we are providing a default in case none of the above match. This
      # will be taken if the update fails, and presumably the view will render
      # appropriate error messages.
      render :edit
    end
  end
end

# app/helpers/posts_helper.rb
module PostsHelper
  def comment_header_for(post)
    case post
    in { comments: [] }
      # Here we're matching against an attribute on the post that is an
      # association. It will go through the association and then match against
      # the records in the relation.
      "No comments yet"
    in { user_id:, comments: [*, { user_id: ^user_id }, *] }
      # Here we're searching for a comment that has the same user_id as the
      # post. We can do this with the "find" pattern. This syntax is all baked
      # into Ruby, so we don't have to do anything other than define the
      # requisite deconstruct methods that are used by the pattern matching.
      "Author replied"
    in { comments: [{ user: { name: } }] }
      # Here we're extracting the first comment out of the comments association
      # and using its associated user's name in the header.
      "One comment from #{name}"
    in { comments: }
      # Here we provide a default in case none of the above match. Since we have
      # already matched against an empty array of comments and a single element
      # array, we know that there are at least two comments. We can get the
      # length of the comments association by capturing the comments association
      # in the pattern itself and then using it.
      "#{comments.length} comments"
    end
  end
end

Installation

Add this line to your application's Gemfile:

gem "rails-pattern_matching"

And then execute:

$ bundle

Or install it yourself as:

$ gem install rails-pattern_matching

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/kddnewton/rails-pattern_matching.

License

The gem is available as open source under the terms of the MIT License.

More Repositories

1

tree

Implementations of the unix tree command
C
248
star
2

preval

Automatically optimizes your Ruby code
Ruby
99
star
3

snip_snip

Snip snip cuts the deadweight
Ruby
90
star
4

humidifier

CloudFormation made easy
Ruby
56
star
5

active_record-union_relation

Create ActiveRecord relations from UNIONs
Ruby
38
star
6

fast_underscore

Fast String#underscore implementation
C
32
star
7

regular_expression

A regular expression engine written in Ruby.
Ruby
29
star
8

gemfilelint

Lint your Gemfile
Ruby
29
star
9

vernacular

Allows extending ruby's syntax and compilation process
Ruby
27
star
10

exreg

A Ruby regular expression engine
Ruby
26
star
11

parser-prism

A prism backend for the whitequark/parser gem
Ruby
23
star
12

travis.ex

Simple Elixir wrapper for the Travis API
Elixir
21
star
13

compiling-ruby

Code for the "Compiling ruby" talk
Ruby
19
star
14

minitest-keyword

Use Minitest assertions with keyword arguments
Ruby
19
star
15

practical-debugging

Code for the "Practical debugging" talk
Ruby
17
star
16

ripper-docs

Documentation for the ripper Ruby standard library
15
star
17

thor-hollaback

Adds callbacks to thor commands
Ruby
14
star
18

sorbet-eraser

Erase all traces of sorbet-runtime code
Ruby
13
star
19

mathlang

A small language for doing math
TypeScript
8
star
20

parsing-ruby

TypeScript
8
star
21

prettier-plugin-ini

A prettier plugin for INI files
JavaScript
8
star
22

hollaback

Add callbacks to your methods
Ruby
8
star
23

attribute_extras

Extra macros for auto attribute manipulation.
Ruby
7
star
24

typescript-parse-math

Parse math expressions with TypeScript types
7
star
25

ruby-parser

A Ruby parser
C
7
star
26

iseq-rails-tools

Use AOT compilation within Rails
Ruby
7
star
27

bundler-console

A bundler plugin that starts a console session with your gem dependencies.
Ruby
6
star
28

wordle

A wordle solver
Ruby
5
star
29

musicxml

Ruby bindings for musicxml
Ruby
5
star
30

yarv

A Ruby object layer on top of the YARV virtual machine
Ruby
5
star
31

ragel-bitmap

Use packed strings for ragel-generated code instead of integer arrays
Ruby
4
star
32

ruby-reprs

Ruby representations
JavaScript
4
star
33

prettier-plugin-brainfuck

Prettier for Brainfuck
JavaScript
4
star
34

taxes

US federal income tax calculator
TypeScript
3
star
35

fast_camelize

Fast String#camelize implementation
Ruby
3
star
36

fast_parameterize

Fast String#parameterize implementation
Ruby
3
star
37

vernacular-ast

Extends Vernacular to support rewriting the AST
Ruby
3
star
38

sql-to-ruby

Parse SQL queries and turn them into equivalent Ruby
Ruby
2
star
39

bonsai

Code for the "Grow a bonsai, not a shrub" talk
Ruby
2
star
40

ripperjs

A wrapper for the ripper Ruby library
C++
2
star
41

lox

A Ruby implementation of the lox language
Ruby
2
star
42

yarp-identifiers

C
1
star
43

pokerpg-builder

Webapp for building pokemon in PokeRPG
TypeScript
1
star
44

unicode-data

A Ruby wrapping for the unicode character data set
Ruby
1
star
45

wm-memories

An app for storing memories from the College of William and Mary.
Ruby
1
star
46

kddnewton.github.io

Personal website
CSS
1
star
47

rubytoolbox-chrome

A Chrome extension for displaying rubytoolbox gem data on rubygems.org
TypeScript
1
star