Skip to content

Instantly share code, notes, and snippets.

@julianrubisch
Created September 23, 2021 11:55
Show Gist options
  • Save julianrubisch/c683f2b79c23c8107fe81dee6741f951 to your computer and use it in GitHub Desktop.
Save julianrubisch/c683f2b79c23c8107fe81dee6741f951 to your computer and use it in GitHub Desktop.
# config/routes.rb
Rails.application.routes.draw do
mount UserStats::Engine, at: "/user_stats"
# ...
end
# lib/user_stats/lib/user_stats/engine.rb
module UserStats
class Engine < ::Rails::Engine
# ...
config.app_middleware.use(
Rack::Static,
urls: ["/packs"], root: "user_stats/public"
)
# ...
end
end
$ cp bin/webpack* lib/user_stats/bin
$ cp config/webpacker.yml lib/user_stats/config
$ cp -r config/webpack lib/user_stats/config
# Gemfile
# ...
gem 'user_stats', path: 'lib/user_stats'
# ...
# lib/user_stats/config/routes.rb
UserStats::Engine.routes.draw do
resources :users, only: :index
root to: "users#index"
end
# /lib/user_stats/app/controllers/user_stats/users_controller.rb
require_dependency "user_stats/application_controller"
module UserStats
class UsersController < ApplicationController
# GET /users
def index
@users = User.all
@reflections = User.reflections.select { |_, val| val.is_a? ActiveRecord::Reflection::HasManyReflection }
end
end
end
# lib/user_stats/app/controllers/user_stats/users_controller.rb
require_dependency "user_stats/application_controller"
module UserStats
class UsersController < ApplicationController
# GET /users
def index
@query ||= params[:query]
@users = @query.present? ? User.where("email ILIKE ?", "%#{@query}%") : User.all
@reflections = User.reflections.select { |_, val| val.is_a? ActiveRecord::Reflection::HasManyReflection }
end
end
end
<!-- lib/user_stats/app/views/user_stats/users/index.html.erb -->
<h1>Users</h1>
<table>
<thead>
<tr>
<th>E-Mail</th>
<th>Created at</th>
<th>Updated at</th>
<% @reflections.each do |key, reflection| %>
<th><%= reflection.name %></th>
<% end %>
</tr>
</thead>
<tbody>
<% @users.each do |user| %>
<tr>
<td>
<%= user.email %>
</td>
<td>
<%= user.created_at.to_s(:long) %>
</td>
<td>
<%= user.updated_at.to_s(:long) %>
</td>
<% @reflections.each do |key, reflection| %>
<td>
<%= user.send(key).count %>
</td>
<% end %>
</tr>
<% end %>
</tbody>
</table>
<!-- lib/user_stats/app/views/user_stats/users/index.html.erb -->
<h1>Users</h1>
<label>Search for E-Mail Addresses</label>
<input type="text" placeholder="Search..." data-reflex="input->UserStats::Tabular#search">
<table>
<!-- ... -->
$ bin/rails g stimulus_reflex UserStats::Tabular search
$ cd lib/user_stats
$ git add .
$ git commit -m "Initial commit"
$ bundle install
$ yarn add @rails/actioncable stimulus [email protected]
$ rails plugin new lib/user_stats --mountable
// lib/user_stats/package.json
{
"name": "user_stats",
"version": "1.0.0",
"private": true,
"dependencies": {
"@rails/webpacker": "5.2.1"
},
"devDependencies": {
"webpack-dev-server": "^3.11.1"
}
}
# lib/user_stats/user_stats.gemspec
Gem::Specification.new do |spec|
# ...
spec.add_dependency "stimulus_reflex", "~> 3.4"
end
// ./lib/user_stats/app/javascript/channels/consumer.j
import { createConsumer } from "@rails/actioncable"
export default createConsumer()
// ./lib/user_stats/app/packs/application.js
import { Application } from "stimulus";
import StimulusReflex from "stimulus_reflex";
import consumer from "../channels/consumer";
const application = Application.start();
StimulusReflex.initialize(application, { consumer, isolate: true });
StimulusReflex.debug = process.env.RAILS_ENV === "development";
application.consumer = consumer;
# lib/user_stats/app/reflexes/user_stats/tabular_reflex.rb
class UserStats::TabularReflex < ApplicationReflex
def search
@query = element[:value].strip
end
end
$ cd lib/user_stats
$ mkdir -p app/javascript/packs
$ touch app/javascript/packs/application.js
$ bin/rails g scaffold User
# lib/user_stats/app/helpers/user_stats/application_helper.rb
module UserStats
module ApplicationHelper
include ::Webpacker::Helper
def current_webpacker_instance
UserStats.webpacker
end
end
end
<!-- lib/user_stats/app/views/layouts/user_stats/application.html.erb -->
<!DOCTYPE html>
<html>
<head>
<title>User stats</title>
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<%= javascript_pack_tag 'application' %>
<%= stylesheet_pack_tag 'application' %>
</head>
<body>
<%= yield %>
</body>
</html>
# lib/user_stats/user_stats.rb
require "user_stats/version"
require "user_stats/engine"
module UserStats
ROOT_PATH = Pathname.new(File.join(__dir__, ".."))
class << self
def webpacker
@webpacker ||= ::Webpacker::Instance.new(
root_path: ROOT_PATH,
config_path: ROOT_PATH.join("config/webpacker.yml")
)
end
end
end
# lib/user_stats/user_stats/engine.rb
module UserStats
class Engine < ::Rails::Engine
isolate_namespace UserStats
initializer "webpacker.proxy" do |app|
insert_middleware = begin
UserStats.webpacker.config.dev_server.present?
rescue
nil
end
next unless insert_middleware
app.middleware.insert_before(
0, Webpacker::DevServerProxy,
ssl_verify_none: true,
webpacker: UserStats.webpacker
)
end
end
end
# lib/user_stats/config/webpacker.yml
development:
# ...
dev_server:
# ...
port: 3036
public: localhost:3036
env_prefix: "USER_STATS_WEBPACKER_DEV_SERVER"
# ...
# lib/user_stats/user_stats.gemspec
Gem::Specification.new do |spec|
# ...
spec.add_dependency "rails", "~> 6.1.4"
spec.add_dependency "webpacker", "~> 5.x"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment