Tag Type
- category of tag
has_many :tags
- optionally belongs to a parent tag type (nested option)
Tag
- specific field
belongs_to :tag_type
- optionally belongs to a parent tag (nested option)
Tag Type
has_many :tags
Tag
belongs_to :tag_type
// - example rails erb view | |
// <div id="edit-react-form" | |
// data-submit-endpoint="<%= billing_profile_path(@billing_profile.token) %>" | |
// data-initial-values="<%= @form.initial_values.to_json %>" | |
// data-cancel-url="<%= billing_profile_path(@billing_profile.token) %>" | |
// > | |
// </div> | |
function parsePropsFromDataset(dataset) { | |
let stringifyedOptions = { ...dataset }; // convert DOMStringMap into Object |
import * as React from "react"; | |
import { SmallButton } from "../../shared"; // a cool <button /> | |
const DisplayLocalStorage = () => { | |
const [changes, setChanges] = React.useState(0); // triggers re-renders | |
let localStorageState = {}; | |
for (let i = 0; i < localStorage.length; i++) { | |
const key = localStorage.key(i); | |
let value; |
import * as React from "react"; | |
import { GET } from "../utils/service"; // a fetch wrapper | |
import { useFilters } from "../hooks"; | |
import FilterForm from "../components/FilterForm"; | |
// filterTemplate instructs useFilters | |
// which filters should be allowed | |
// and how they are to traverse the data object tree |
# based on https://intellipaat.com/community/16534/is-there-a-way-to-print-javascript-console-errors-to-the-terminal-with-rspec-capybara-selenium | |
class ApplicationSystemTestCase < ActionDispatch::SystemTestCase | |
JavaScriptError = Class.new(StandardError) | |
driven_by :selenium, using: :headless_chrome, screen_size: [1400, 1400] | |
def teardown | |
logs = page.driver.browser.manage.logs.get(:browser) | |
errors = logs.select { |e| e.level == 'SEVERE' && e.message.present? } |
const getPasswordToggleStyle = offsetEl => { | |
const top = offsetEl.offsetTop + 6; | |
const left = offsetEl.offsetLeft + offsetEl.clientWidth - 28; | |
return `position: absolute; top: ${top}px; left: ${left}px; max-height: 16px; vertical-align: top; padding: 0; z-index: 7;`; | |
}; | |
const addPasswordToggle = domId => { | |
const el = document.getElementById(domId); | |
if (!el) return; |
import { useEffect, useRef } from "react"; | |
import debounce from "lodash/debounce"; | |
// basically a save-dedicated clone of | |
// a hook that would be called useDebouncedCallback | |
const AutoSave = ({ | |
values, // what's in the form | |
saveProgress, // a network request / api call | |
interval = 5000, // ms | |
}) => { |
# frozen_string_literal: true | |
module Abilities | |
module AbilityDelegator | |
def self.included(klass) | |
klass.class_eval do | |
def delegate_action(action_or_actions, to:, traversal:, user:) | |
actions = [*action_or_actions] | |
can actions, model_class do |instance| | |
delegate = traversal.reduce(instance, &:public_send) |
// I put this in app/index.js but you do you! | |
import React, { Suspense, lazy } from "react"; | |
import PropTypes from "prop-types"; | |
import { Route, Switch } from "react-router-dom"; | |
import { SharedProvider } from "../../../modules/something/context"; // to easily share state without going full redux | |
import SharedHeader from "../../widgets/employees/Header"; // some shared header | |
import SomeMenu from "./SomeMenu"; // some shared navigation | |
import { ThreeDotLoader } from "../../shared"; // simple loader |
require 'google/apis/sheets_v4' | |
require 'google/apis/drive_v3' | |
require 'googleauth' | |
require 'fileutils' | |
class GoogleSheetReportWriter | |
def initialize(notification_email:) | |
@creds = build_credentials | |
@notification_email = notification_email | |
end |