diff --git a/.node-version b/.node-version new file mode 100644 index 0000000..8783404 --- /dev/null +++ b/.node-version @@ -0,0 +1 @@ +20.12.2 diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 0000000..b347b11 --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +3.2.3 diff --git a/.tool-versions b/.tool-versions index 5dcac6e..c75ae41 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ -ruby 2.7.6 -nodejs 16.15.0 +ruby 3.2.3 +nodejs 20.12.2 diff --git a/Gemfile b/Gemfile index b8b33bb..32f2cbd 100644 --- a/Gemfile +++ b/Gemfile @@ -33,3 +33,4 @@ end # Performance-booster for watching directories on Windows gem "wdm", "~> 0.1.1", :install_if => Gem.win_platform? +gem "webrick", "~> 1.8" diff --git a/README.md b/README.md index fc65624..d8db706 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,14 @@ +[![Netlify Status](https://api.netlify.com/api/v1/badges/2d6ef4e0-f240-4fdf-9434-d6756a8e2fb9/deploy-status)](https://app.netlify.com/sites/silly-rosalind-46cc1c/deploys) + ## Steps to use - Create a new repo, using this one as the template. - Run `bundle install` (might need to run `gem install bundler` first) - Run `yarn install` - Run `jekyll server` - Continue development + +## More + +Check out my personal site: https://craigpetterson.co.uk + +Following me on Twitter: [@JalisoCSP](https://twitter.com/JalisoCSP) diff --git a/_includes/footer.html b/_includes/footer.html index 09b9cc9..739a16a 100644 --- a/_includes/footer.html +++ b/_includes/footer.html @@ -23,20 +23,34 @@
- + + Twitter + + + + + - + + GitHub + LinkedIn
- + {{ site.email }} - +
diff --git a/_includes/projects.html b/_includes/projects.html index 8c8d966..6d38df8 100644 --- a/_includes/projects.html +++ b/_includes/projects.html @@ -13,60 +13,41 @@

-
+ +
-
-
-
- - {% include svg/pandle.svg %} - -
+
+ + {% include svg/pandle.svg %} + +
+

+ Accountancy Software +

+

+ A cloud-based accountancy software with an extensive feature list + to help make bookkeeping simple. Originally developed in a + sophisticated and intuitive manner with small UK businesses in + mind. +

+ + + + + + Review +
+ -->
-
-
-
- +
+ Pandle Homepage Screenshot
@@ -74,42 +55,39 @@

+
-
-
-
- - {% include svg/doorflow.svg %} - -
+
+ + {% include svg/doorflow.svg %} + +
+

+ Access Control Software +

+

+ Cloud-based access control system for secure areas. Used by + co-working spaces, offices, schools, universities, sports + clubs and more. Handles entirely remotely, no software + installation or maintenance is required. +

+ + + + + + Review +
+ -->
-
-
- +
+ Doorflow Homepage Screenshot
@@ -117,87 +95,40 @@

-
-
-
-
-

- Let's upgrade your software -

-

- Use an expert. I have experience maintaining a variety of software - applications, from single person development projects to teams with - dozens of developers, from green-field projects to decades old - legacy codebases. -

- - - - Contact Me - -
-
-
- -
-
+
-
-
-
- - {% include svg/zapnito.svg %} - -
+
+ + {% include svg/zapnito.svg %} + +
+

+ Community Platform +

+

+ A intelligent platform to enhance community management that allows + members to learn, share and collaborate. This platform provides + all the tools required to engage, retain and grow your + communities so your users stay longer, spend more and encourage + others to do the same. +

+ + + + + + Review +
+ -->
-
-
-
- +
+ Zapnito Homepage Screenshot
@@ -205,47 +136,45 @@

+
-
-
-
- - DVLA Search - -
+
+ + DVLA Search + +
+

+ Vehicle Search API Account Management +

+

+ I led a small team to produce an account management system for + software that helps access detailed vehicle information. This + system is used to manage payments for the service as well as user + permissions, invoicing and historical information. +

+ + + + + + Review +
+ -->
-
-
- +
+ DVLA Search Homepage Screenshot
- + +
diff --git a/_includes/svg/socials.html b/_includes/svg/socials.html index b2ed68f..dd27c71 100644 --- a/_includes/svg/socials.html +++ b/_includes/svg/socials.html @@ -1,24 +1,34 @@ -
+ - -
+ + - - + + diff --git a/_posts/2024-07-08-installing-tailwindcss.md b/_posts/2024-07-08-installing-tailwindcss.md new file mode 100644 index 0000000..da8e56b --- /dev/null +++ b/_posts/2024-07-08-installing-tailwindcss.md @@ -0,0 +1,91 @@ +--- +layout: article +category: articles +tags: technical + +title: "Foreman error when installing TailwindCSS" +--- + +I followed the steps on the Tailwind website to [Install TailwindCSS with Ruby on Rails](https://tailwindcss.com/docs/guides/ruby-on-rails) + +When I ran `bin/dev`, I had an issue with `foreman`... + +``` +bin/dev: line 16: exec: foreman: not found +``` + +It’s likely a pathing issue, because my gems get installed in `vendor/bundle` and that’s not in my `$PATH`. I was able to resolve this by installing foreman via brew, as [recommended on StackOverflow](https://stackoverflow.com/a/77369749) (yes, I copy and pasted random code from SO) + +``` +brew install foreman +``` + +However, I realised that Tailwind had added a `bin/dev` file which was just calling the commands in the `Procfile.dev` file. This was just merging the `bin/rails server` process with the `bin/rails tailwindcss:watch` so it was on the same pane. + +It’s nice, but it’s not necessary. + +Using the `bin/dev` option actually adds a bit of fluff by adding the timestamp and the process name to the beginning of each line: + +``` +craig@MacBook-Pro tailwind-example % bin/dev +23:11:14 web.1 | started with pid 100 +23:11:14 css.1 | started with pid 101 +23:11:16 web.1 | => Booting Puma +23:11:16 web.1 | => Rails 7.1.3.4 application starting in development +23:11:16 web.1 | => Run `bin/rails server --help` for more startup options +23:11:17 web.1 | Puma starting in single mode... +23:11:17 web.1 | * Puma version: 6.4.2 (ruby 3.3.2-p78) ("The Eagle of Durango") +23:11:17 web.1 | * Min threads: 5 +23:11:17 web.1 | * Max threads: 5 +23:11:17 web.1 | * Environment: development +23:11:17 web.1 | * PID: 100 +23:11:17 web.1 | * Listening on http://127.0.0.1:3000 +23:11:17 web.1 | * Listening on http://[::1]:3000 +23:11:17 web.1 | Use Ctrl-C to stop +23:11:18 css.1 | +23:11:18 css.1 | Rebuilding... +23:11:18 css.1 | +23:11:18 css.1 | Done in 844ms. +23:12:55 css.1 | +23:12:55 css.1 | Rebuilding... +23:12:55 css.1 | +23:12:55 css.1 | Done in 176ms. +``` + +We can run these commands separately with no issues: +* `bin/rails s` +* `bin/rails tailwindcss:watch` + +``` +craig@MacBook-Pro tailwind-example % bin/rails s +=> Booting Puma +=> Rails 7.1.3.4 application starting in development +=> Run `bin/rails server --help` for more startup options +Puma starting in single mode... +* Puma version: 6.4.2 (ruby 3.3.2-p78) ("The Eagle of Durango") +* Min threads: 5 +* Max threads: 5 +* Environment: development +* PID: 743 +* Listening on http://127.0.0.1:3000 +* Listening on http://[::1]:3000 +Use Ctrl-C to stop +``` + +AND + +``` +craig@MacBook-Pro tailwind-example % bin/rails tailwindcss:watch + +Rebuilding... + +Done in 716ms. +``` + +Maybe I’m biased because it’s no extra effort for me, since I use tmuxinator and open my projects with a single command. By putting them in separate panes, I was able to completely delete the `bin/dev` and `Procfile.dev` files from my codebase. + +### Notes +* For me, using a `bin/dev` command when I'm used to doing `bin/rails` isn't worth it. I imagine it's worth it for teams or projects with more commands. +* I probably need to update my gem paths, so that running commands like foreman just works straight away. +* I really love just having a simple tmux command to run ever process when I start developing. +* I really love removing fluff like this from my projects. diff --git a/_posts/2024-10-01-querying-json-columns.md b/_posts/2024-10-01-querying-json-columns.md new file mode 100644 index 0000000..b91369c --- /dev/null +++ b/_posts/2024-10-01-querying-json-columns.md @@ -0,0 +1,21 @@ +--- +layout: article +category: articles +tags: technical + +title: "Querying JSON columns" +--- + +This is written from a bad example, but we have a model that can have many widgets, which are all saved in a JSON column. I know I just said `has_many`, so really we should refactor this. However, that's a separate refactor for another time. + +We were removing a specific widget, but I didn't know how to verify where it was being used programmatically. + +Turns out, you can dig through a JSON column by casting it to `jsonb` and using an arrow operator `->` and then query a specific key using `@>` + +As an example, if I wanted to check out my model's `column` attribute for any `widgets` with the `type: 'widget_name'`. + +``` +Model.where("column::jsonb -> widgets @> ?", [{ "type" => "widget_name" }].to_json) +``` + +I original thought the column _was_ a `jsonb` type. It was not, but I was able to cast it to `jsonb` using `column::jsonb`. Without casting it to `jsonb` this would raise operation errors: `operator does not exist: json @> unknown` diff --git a/index.html b/index.html index 254f91e..97d78d1 100644 --- a/index.html +++ b/index.html @@ -60,6 +60,23 @@

+
+
+

+ Let's chat! +

+

+ Book some time to talk directly with me +

+
+
+ +
+ + + +
diff --git a/package-lock.json b/package-lock.json index 39dac54..fa02a75 100644 --- a/package-lock.json +++ b/package-lock.json @@ -215,11 +215,11 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -688,9 +688,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -999,11 +999,11 @@ } }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -1028,9 +1028,9 @@ "dev": true }, "node_modules/nanoid": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", - "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", "funding": [ { "type": "github", @@ -2488,11 +2488,11 @@ } }, "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "requires": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" } }, "browserslist": { @@ -2820,9 +2820,9 @@ } }, "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "requires": { "to-regex-range": "^5.0.1" } @@ -3049,11 +3049,11 @@ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" }, "micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "requires": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" } }, @@ -3072,9 +3072,9 @@ "dev": true }, "nanoid": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", - "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==" + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==" }, "node-releases": { "version": "2.0.6", diff --git a/projects.html b/projects.html index ce40eaa..1bc7bbb 100644 --- a/projects.html +++ b/projects.html @@ -4,3 +4,29 @@ --- {% include projects.html %} + +
+
+
+

+ Partner with an expert +

+

+ My experience covers single person development projects, teams with + dozens of developers, green-field projects and decades old legacy + codebases. +

+

+ Let my expertise drive your success. +

+ + + + Contact Me + +
+
+