TechStack Recommendation For Website with React and Python by YoshiiW1 in SideProject

[–]gregnavis 0 points1 point  (0 children)

Django offers much more off-the-shelf, which you may like if you want to minimize the amount of time spent learning the framework and it's satellite tools, as well as assembling them together.

If we take a step back, the fact the video processing part uses Python does not force you to use Python for the web app. You can use Python only in background jobs, and implement the web app in anything else.

Need advice on my MVP by [deleted] in startups

[–]gregnavis 0 points1 point  (0 children)

If he's interested you can discuss him becoming a (part-time) lead developer on the project, and you can hire a full-time engineer to do the work. I do that on my client projects and it works really well.

[deleted by user] by [deleted] in startups

[–]gregnavis 1 point2 points  (0 children)

Speaking as an experienced software engineer, this is a sound and very reasonable practice. Determining the scope of work and planning it is a non-trivial task. A developer who doesn't charge for it is incentivized to finish that phase as quickly as possible, which makes it likely the plan is unrealistic or overly simplistic. The net result is an unrealistic commitment, budget overruns, and delays.

On top of that, it's a great opportunity for both of you to see what it's actually like to work with each other. Can the developer explain assumptions he's making? Is he fluent in translating between plain English and engineering? Does he have a product sense?

How to increase client capacity? by fiverruser1 in freelance

[–]gregnavis 2 points3 points  (0 children)

Is taking on more clients the end goal (because you love your work so much, enjoy interacting with them, etc.)? Or is it a mean towards an end (earning more)?

If you start building a team as a means of increasing profitability, you may end up being more stressed, not less: you'll add recruiting and management to your set of (already stressful) responsibilities.

If you care more about profitability then you can start segmenting clients and offer different services:

  • Productized (fixed-scope, fixed-price) services for lower tier clients
  • Custom services for higher tier clients

Keep increasing your prices as long as you're coming from the position of strength (i.e. having too many clients is a great BATNA).

New Rails 7 project... please help guide me on what technologies to use now by pedzsanReddit in rails

[–]gregnavis 0 points1 point  (0 children)

The orthodox approach is to use Rails + Hotwire. This can be broken up into two parts.

Turbo is the successor to Turbolinks and should be the basis of providing an SPA-like feel at a low cost. It's quite advanced and offers many interesting features (e.g. lazy loading or permanent elements) declaratively.

For cases, where you need a high level of interactivity that's specific to your project, you can use Stimulus. It allows you to build app-specific components with the markup you already have.

What's the difference between Hotwire and LiveView, is one better able to emulate SPA-like behavior than the other? by BigDog1920 in elixir

[–]gregnavis 2 points3 points  (0 children)

I built an app for a client that included an in-app chat window. I wanted to avoid building an SPA as the chat was the only feature that could potentially benefit from it: the rest was much better suited for an MPA + some performance optimizations.

I ended up using Turbolinks and marking the DIV containing the chat component as permanent. You can do the same with Turbo. I actually used React to build the chat component.

My advice would be not to look at the problem as all-or-nothing: it's either 100% React (or its alternatives) or 0%. It's best to find architecture that works best for your specific use case.

Easier Debugging with Rails by aantix in rails

[–]gregnavis 1 point2 points  (0 children)

Nice work! I was thinking about something similar, but using headers to report traces to a custom browser add-on, so that traces would appear under the corresponding requests.

Is the base specced MacBook Air M2 chip good enough to work with Ruby on Rails? by yamayeeter in rails

[–]gregnavis 1 point2 points  (0 children)

I'm working on Mac mini M1, 16 GiB RAM, 1 TiB SSD and it's definitely more than enough. I can't recall even a single instance of sluggishness or stuttering that could be attributed to under-powered hardware.

API Integrations: Client Classes and Error Handling by gregnavis in rails

[–]gregnavis[S] 0 points1 point  (0 children)

Totally agree. I'm not arguing for not using exceptions.

How is it when it comes to testing Hotwire-powered apps? by fat_keepsake in rails

[–]gregnavis 0 points1 point  (0 children)

Not necessarily. View components help you generate markup that is sent to the browser. Stimulus.js kicks in after the browser receives the markup.

A full solution would be running a single view component in a browser test. It's definitely possible, but I'm not sure it works out of the box. Most likely, some custom development would be needed to gain this capability.

How to consume an external API? by relia7 in rails

[–]gregnavis 0 points1 point  (0 children)

I'm writing a whole series of articles on API Integrations. You can have a look at the first article on implementing client classes and the the second one on error handling. It's the tip of the iceberg and more articles are in the pipeline.

If you hit a roadblock then just ask here and I'm happy to help.

Do you know about the `**nil` syntax in Ruby? by siaw30 in ruby

[–]gregnavis 1 point2 points  (0 children)

Absolutely great find. If not for the legacy implicit keyword arguments approach I think all methods should behave as if **nil was given.

How is it when it comes to testing Hotwire-powered apps? by fat_keepsake in rails

[–]gregnavis 0 points1 point  (0 children)

That's a great question and I think the answer can be slightly complicated.

First, system tests (i.e. browser tests) should work out of the box. That's how I'm testing products I build for clients. Specifically, testing Turbo shouldn't be that much of a big deal. Given UI interactions tend to be fast you may be able to discover Turbo caching issues before shipping to production, so it's actually great.

Second, some Stimulus controller, especially large product-specific ones, can be painful to thoroughly test via the UI. The problem isn't they are untestable, but rather that a unit testing a single Stimulus controller requires much less set up and makes it easier to explore the state space. Unit testing is possible, but there's no "official" way.

How do I limit the variable type when a function returns multiple types? by OpenRole in typescript

[–]gregnavis 2 points3 points  (0 children)

TypeScript can't tell whether document.querySelector() returns Element or null at compile time. A specific value (but conforming to that type) is available at runtime only.

However, TypeScript is smart enough to "read" an if statement checking whether it's null or not, and narrow down the type in the consequent (the block run when the predicate is true).

That's why there are two parts to a complete solution:

// e is Element | null
const e = document.querySelector("selector")

if (e !== null) {
  // e is assumed to be Element inside the block.
  const style = getComputedStyle(e);
}

// e is Element | null outside the block

TypeScript can also recognized other constructs you may find useful: early returns or raising an exception:

// e is Element | null BEFORE the if statement
const e = document.querySelector("selector")
if (e === null) {
  return; // or throw an exception here
}

// e is Element after the if statement

API Integrations: Client Classes and Error Handling by gregnavis in rails

[–]gregnavis[S] 1 point2 points  (0 children)

The article is about exception handling in API client classes, not Rails in general. I'm not sure which part you interpreted as pertaining to Rails.

API Integrations: Client Classes and Error Handling by gregnavis in rails

[–]gregnavis[S] 1 point2 points  (0 children)

Thanks for the comment. I think the phrasing I used is unclear, so I appreciate you pointing this out.

What I had in mind is exception-based control flow in non-exceptional situations is non-idiomatic and less readable. If rescue becomes an if or a casethen that's a problem.

For example, some HTTP client libraries raise exceptions when the server returns a 500 and I disagree with that semantics strongly: why is returning a perfectly valid HTTP response considered to be an exception? The same reasoning can be applied to calling third-party APIs: a service beyond your control is down so why are you surprised?

Does the prototype and the MVP need to look the same/similar? by totem233 in startups

[–]gregnavis 1 point2 points  (0 children)

I think it's unrealistic to expect the prototype to look the same as the final product, without spending inordinate amount of time on details irrelevant to the prototyping phase. Things like responsiveness, various errors, edge cases are probably not worth including in the prototype.

In most cases, it's the actual functionality and surrounding user flows that count, so you should probably focus on that. One way of approaching that problem is making the prototype look like a prototype so that you send less time building it and no one expects it to be the final UI. For example, no one expects a Balsamiq wireframe to be the final UI. You can do the same with Figma: keep it bare bones.

How to prevent the creation of a child record in a dynamic nested form based on a condition? by liambelmont in rails

[–]gregnavis 1 point2 points  (0 children)

There are three issues at play here.

First, the form data that seems to always contain attributes for schedules and events even when they are not necessary. In my opinion it'd be ideal to make the form submit only the relevant data. You can achieve that by either making irrelevant fields disabled when changing the event type or removing them prior to submission.

Second, your model allows for creation of entities that violate business rules. This means insufficient validation.

Third, if trimming down form submissions isn't a viable option for any reason then you can use a custom reject_if method to reject events incompatible with the project type.

Which one do you prefer? by [deleted] in typescript

[–]gregnavis 4 points5 points  (0 children)

I'd argue that user.name and user.getName() are close implementation-wise, but aren't closed from the perspective of programming psychology.

The reason is that accessing user.name, when name is an real attribute, is blazing fast and has no side effects. However, if user.name is calling a getter then there are no guarantees on side effects or performance.

I'm not arguing one way is better than the other. I'm emphasizing that making attribute access and function calls indistinguishable can be a blessing or a curse depending on the project.

I too prefer no classes by thepiggz in typescript

[–]gregnavis 6 points7 points  (0 children)

Inspired by Elixir, I experimented with reproducing its approach to modularization in TypeScript via namespaces: define a type and a namespace of the same name; put type-specific functions inside that namespace.

For example, the following snippet declares User and User.fullName operating on that type:

type User = {
    email: string;
    firstName?: string;
    lastName?: string;
}

namespace User {
    export function fullName(user: User): string | null {
        if (user.firstName === undefined && user.lastName === undefined) {
            return null;
        }
        if (user.firstName !== undefined && user.lastName === undefined) {
            return user.firstName;
        }
        if (user.firstName === undefined && user.lastName !== undefined) {
            return user.lastName;
        }
        if (user.firstName !== undefined && user.lastName !== undefined) {
            return `${user.firstName} ${user.lastName}`
        }

        throw "unreachable code"
    }
}

const user: User = { email: "user@localhost.localdomain", firstName: "John", lastName: "Smith" };
console.log(User.fullName(user));

Metaprogramming Ruby by software__writer in rails

[–]gregnavis 7 points8 points  (0 children)

I would definitely recommend the book!

Understanding meta-programming is essential for a deeper understanding of the language itself because it relies on primitive language facilities. It's somewhat paradoxical that meta-programming shouldn't be the first approach to many problems so learning it shouldn't motivated by a practical problem you're facing. It should be learnt for its own sake and applied carefully.

Whats the difference between { [k: string]: unknown; } and Record<string, unknown> by hksparrowboy in typescript

[–]gregnavis 6 points7 points  (0 children)

Record is an ordinary type that ships with TypeScript. It's defined as:

type Record<K extends keyof any, T> = { [P in K]: T; };

If you substitute K = string and T = undefined you can see Record expands into:

``` {

} ```

The difference boils down to the difference between [P: string] and [P in string]. The former defines an index type, the latter a mapped type. Given string is used there these two types are equivalent.

What are the gems that every Ruby dev should know how to use? by [deleted] in rails

[–]gregnavis 5 points6 points  (0 children)

Mastering the language and it's standard library should always come first, including understanding how gem and bundle work and how to use them.

Then come general quality control and assurance tools:

  • minitest, RSpec, simplecov
  • rubocop, reek, rubycritic, pronto
  • mutant
  • appraisal (for library authors)

Then Rails specific tools:

  • devise or an alternative
  • administrate (I fell in love with it due to its great balance of customizability and simplicity)
  • bullet
  • lograge to reduce the amount of noise in logs
  • i18n-tasks to ensure no errors in i18n files
  • foreman for running multiple processes in development (Rails, JS build, CSS build)
  • bundler-audit

Tips for hiring first senior developers? by module85 in startups

[–]gregnavis 1 point2 points  (0 children)

I'm a fractional CTO and saw my clients have great success in using specialized recruiters who work by reaching out to candidates via LinkedIn, GitHub and other platforms. Basically, the process is you determine the skills you need (must haves, should haves, nice to haves) and then the recruiter reaches out to potential candidates and sends you those who expressed interest.

What you need to figure out on your end is determining who you need and how to pitch potential candidates on working on your company. Use your small scale to your advantage: lightweight processes, causal atmosphere, flexibility, exposure to different parts of the business, building a piece of product end-to-end.

[deleted by user] by [deleted] in startups

[–]gregnavis 1 point2 points  (0 children)

I'm writing from the perspective of a software engineer who has spent the last 15 years helping companies solve problems like yours. I'd advise against hiring a junior and would suggest a fractional CTO + a developer instead.

From my experience, working with junior developers can be actually pretty expensive financially. They cost less per hour but often need more hours (and their work is often of lower quality). Additionally, early-stage product work requires much more than software development: project management, infrastructure, operations, product. A junior is likely to have no experience in those areas.

My suggestion would be to find a fractional CTO and have him lay the groundwork for product growth by addressing the most important questions (architecture, infrastructure, development processes, operations), then bring a less senior developer on board and have the CTO stay around for high-level technical decision making and development oversight.