profile
viewpoint
David Heinemeier Hansson dhh Basecamp Malibu, CA https://dhh.dk

github/gemoji 3500

Emoji images and names.

dhh/tolk 530

Tolk is a web interface for doing i18n translations packaged as an engine for Rails 2.3 applications

dhh/custom_configuration 206

Custom configuration storage for Rails

qrush/motion-settings-bundle 113

Create a Settings.bundle for your RubyMotion app

dhh/asset-hosting-with-minimum-ssl 79

Rails plugin for picking a non-ssl asset host as often as possible

dhh/delayed_job 35

Database based asynchronously priority queue system -- Extracted from Shopify

dhh/will_paginate 24

Adaptive pagination plugin for web frameworks and other applications

dhh/country_and_region_select 22

Country and Region Select Plugin

bf4/code_metrics 19

Extracting Code Statistics from rails

pull request commentbasecamp/full_request_logger

Support storing full request logs for jobs

I think this is a fine way for now. If we end up continuing to like this, we should upstream with a few changes 👍

rosa

comment created time in 3 days

push eventbasecamp/name_of_person

Benjamin Hargett

commit sha 2cdefdeea8fddfa7f462eba3aebb442abcbc3bf6

Add support for most formats in the possessive method (#9)

view details

push time in 21 days

PR merged basecamp/name_of_person

Reviewers
Add support for reasonable name formats in the possessive method

This extends the possessive method functionality by opening it up to using a whitelisted set of PersonName methods.

It allows full, first, last, abbreviated, sorted, and initials formats.

person.name.possessive(:first)  # => "David's"
  • [x] Changes Tested
+42 -2

0 comment

3 changed files

bharget

pr closed time in 21 days

pull request commentrails/rails

Rendering objects that respond_to render_in uses class, not instance

I think a good way to think about this is that the component should essentially return a string that these other features wrap around, like layout. But that anything that is an instruction to the component itself on how to render should be passed to the component via the initializer.

joelhawksley

comment created time in 21 days

issue commentrails/rails

Add ActionCable::Channel.stream_or_reject_for

Have at it! You can reference this ticket in your PR 🙏❤️

On Sun, Feb 2, 2020 at 7:50 PM "github.com" notifications@github.com wrote: “@dhh I would like take this up.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.”

dhh

comment created time in 22 days

pull request commentrails/webpacker

Rename javascript folder to frontend

Nothing has changed on the fundamentals for me. We're happily using Webpack for JavaScript and the asset pipeline for styles and static assets in a brand new app. I find it to be a great combination.

Happy to entertain a patch that makes it easier to rename this for people who'd like to do that, if there are any blockers in that department, but no appetite for changing the defaults at the moment.

yvbeek

comment created time in 22 days

issue openedrails/rails

Add ActionCable::Channel.stream_or_reject_for

This is a very common pattern:

class MyChannel < ApplicationCable::Channel
  def subscribed
    if box = identity.boxes.find_by(id: params[:id])
      stream_for box
    else
      reject
    end
end

You're looking for a record based on a parameter, and if you find it, you'll start streaming. If the record isn't there, you reject the connection. We should extract Add ActionCable::Channel.stream_or_reject_for so you can just write:

class MyChannel < ApplicationCable::Channel
  def subscribed
    stream_or_reject_for identity.boxes.find_by(id: params[:id])
end

Implementation:

def stream_or_reject_for(record_or_nil)
  if record = record_or_nil
    stream_for record
  else
    reject
  end
end

Needs testing, documentation, etc.

created time in 23 days

pull request commentrails/rails

Rendering objects that respond_to render_in uses class, not instance

Hey Joel,

I don't see the API improvement going from render(MyComponent.new(title: "Hello, World!") to render(MyComponent, title: "Hello, World!"). There's more indirection (now Rails is responsible for instantiation), and there's no pay-off in clarity or brevity. I think just dealing with objects that respond to methods is a simpler approach.

Secondly, I think it's better to consider collection rendering as a responsibility of the component, rather than something this API needs to accommodate. So something like render(MyCollectionComponent.new(@people)). Or, given that this is indeed just objects, you could potentially do render(MyComponent.new(@person)) and render(MyComponent.collection(@people)).

joelhawksley

comment created time in 24 days

issue commentrails/webpacker

How to use this gem from within rails engines?

I’d very much like to see engines supported by webpacker.

On Fri, Jan 24, 2020 at 1:43 PM "github.com" notifications@github.com wrote: “Hi @dhh thanks for paying attention 🙏 What are your thoughts on this topic in general? Should webpacker support engines out of the box or should engine authors figure it out on their own?”

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

fiedl

comment created time in a month

issue commentrails/webpacker

How to use this gem from within rails engines?

Maybe @wycats has an idea here, given his work on yarn? On Fri, Jan 24, 2020 at 1:23 PM "github.com" notifications@github.com wrote: ““installed by yarn locally from engines directory””

“I was unable to figure out any way to get that to happen, in a way that would work with standard deployment scenarios. Because the relative and absolute paths of a gem dependency can change between local machine and remote deployment machine and the relative path on remote deployment machine can depend on exactly what ruby technologies you are using (bundler local or not, rvm or not set up how, etc).

If a future version of yarn supports custom plugins, so there could be some custom dynamic logic, that could do it. But without that, yarn (outside of rails or webpacker's control) wants a path as a simple string in the package.json/yarn.lock -- and we want to be able to commit those files to the repo, and not have them have to change depending on deployment environment.”

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

fiedl

comment created time in a month

pull request commentrails/rails

Finding Orphan Records

Seems like some build failures?

tomrossi7

comment created time in 2 months

PR closed rails/rails

implicitly translate flash messages with redirect_to actionpack

Summary

analogous to how form.text_field :foo, placeholder: true will enable and implicitly lookup the proper translation of the field's placeholder, do so with redirect_to foo_path, notice: true as well and give me the proper translated flash from I18n.

yesterday is was getting sick of typing over and over again:

redirect_to foo_path, notice: t(".notice")
# and
redirect_to foo_path, alert: t(".alert")

so i got around implementing this:

redirect_to foo_path, notice: true
# and
redirect_to foo_path, alert: true

Notes

  • this makes AC::Flash implicitly dependent upon AbstractController::Translation
  • this only works for "known" flash types (by default notice and alert) and such added with add_flash_types
  • it only kicks in if the flash value is true, otherwise keeps the original behavior
+34 -1

2 comments

2 changed files

glaszig

pr closed time in 2 months

pull request commentrails/rails

implicitly translate flash messages with redirect_to

Sympathize with the desire to cut down on repetition, but I don't see this one happening. It's not at all clear from just passing true that it would go through i18n, and I don't like the added dependency either. Going to pass on this one. You could essentially do the same in your app by adding redirect_with_notice_to url.

glaszig

comment created time in 2 months

pull request commentrails/rails

Remove reference to global rails command in the docs

I still want to see this. Where I most want to see it is in the console output by the test runner! So I can just copy and paste that line and it’ll actually work. Anyway we should still do all of this. Mind taking another stab? I’ll assign to myself and push through.

hahmed

comment created time in 2 months

PullRequestEvent
PullRequestEvent

pull request commentrails/rails

Finding Orphan Records

@tomrossi7 could you add a change log entry? I’ll merge 👍

tomrossi7

comment created time in 2 months

PullRequestEvent
PullRequestEvent

push eventbasecamp/handbook

John Williams

commit sha eebc93056bcae125caa52dc34b7cffd918216c6b

Add section about 40/32 hour work weeks.

view details

John Williams

commit sha 2bfcfc35e162dad7693f3e9e7b3a3906cb846250

Less wordy

view details

David Heinemeier Hansson

commit sha f51750679503425ad7ac4f5aaebbb3d2e1658f72

Merge pull request #83 from basecamp/balanced 40 Hour Work Weeks

view details

push time in 2 months

PR merged basecamp/handbook

Reviewers
40 Hour Work Weeks
+7 -0

0 comment

1 changed file

johnwilliams

pr closed time in 2 months

pull request commentrails/rails

Add reflected association methods to relations

Nice! Haven't looked at the implementation, but does this go turtles all the way down? Wonder what the full Blogs.all.categories.posts.comments query would look like/perform? If it's all just done with subqueries.

kddeisz

comment created time in 2 months

PR closed rails/rails

Improve readability of default scaffolds design railties

Summary

I've always found the default styles of scaffolds.css to be hard to read, with small, dense text. In this PR, I've increased the text size & readability, switched to system fonts, & brightened the colors. There's no advanced CSS features, just updated the basics with the same mentality of the original.


I anticipate some hesitation on this PR based on:

Changes that are cosmetic in nature and do not add anything substantial to the stability, functionality, or testability of Rails will generally not be accepted.

https://github.com/rails/rails/pull/24321#issuecomment-207348333

For the reasons I outlined above, I think this is a worthwhile change, but I haven't contributed to Rails before, so I super hope I'm not wasting your time <3

Design & CSS are obviously super subjective, so happy to make requested changes there.

<!-- Provide a general description of the code changes in your pull request... were there any bugs you had fixed? If so, mention them. If these bugs have open GitHub issues, be sure to tag them here as well, to keep the conversation linked together. -->

Other Information

Screenshots:

Screen Shot 2019-07-08 at 10 41 55 PM Screen Shot 2019-07-08 at 10 42 07 PM Screen Shot 2019-07-08 at 10 42 34 PM

+116 -46

2 comments

2 changed files

lachlanjc

pr closed time in 2 months

pull request commentrails/rails

Improve readability of default scaffolds design

I appreciate this initiative, but the scaffold is supposed to be ugly. It's ugly because it's intended to be changed. This is unlike, say, the Django admin, which is intended to be used as is. ✌️

lachlanjc

comment created time in 2 months

push eventbasecamp/handbook

David Heinemeier Hansson

commit sha 59c25e443519e43baa1eb4949fda8e1a544066d4

Raises bump pay immediately

view details

push time in 2 months

push eventbasecamp/handbook

David Heinemeier Hansson

commit sha 8cc1d806538c937b6e17015781f1e1ee4f2efd41

Note that we've been giving CPI raises as well

view details

push time in 2 months

pull request commentrails/rails

Active storage add proxying

(sorry, closed by a mistake!)

fleck

comment created time in 2 months

PullRequestEvent

PR closed rails/rails

Active storage add proxying activestorage docs railties

Summary

Added the option to globally change how active storage files are delivered. Users can now set app.config.active_storage.delivery_method to [*:redirect, :proxy]. There's also the option to override at the model level using has_one_attached :avatar, delivery_method: :proxy syntax.

This is just a rough draft, still could be DRYed up a bit, needs tests, and documentation. Just want to get some feedback before I go to far.

Other Information

If you are updating any of the CHANGELOG files or are asked to update the CHANGELOG files by reviewers, please add the CHANGELOG entry at the top of the file.

Finally, if your pull request affects documentation or any non-code changes, guidelines for those changes are available here

+380 -63

43 comments

26 changed files

fleck

pr closed time in 2 months

pull request commentrails/rails

Active storage add proxying

@fleck Thanks for your continued work on this! I like the breakout of the controllers a lot. Where I'm not on board is all the model and default configuration. I'd rather see that this is all being run through normal routes. So if you add a way to do imgproxy, it's a view concern. You add a route and a controller that goes with that route, and that's that. Same with the proxy path. We don't need a modeling configuration for this.

fleck

comment created time in 2 months

Pull request review commentrails/rails

Bring back feature that allows loading external route files:

 video = Video.find_by(identifier: "Roman-Holiday") edit_video_path(video) # => "/videos/Roman-Holiday/edit" ``` +Breaking up *very* large route file into multiple small ones:+-------------------------------------------------------++If you work in a large application with hundreds if not thousands of routes,

I'd say the cut-off is thousands. We have 500+ at Basecamp, and the split is def not worth it there.

Edouard-chin

comment created time in 3 months

issue openedrails/rails

Bring Many monad to ActiveSupport and Active Record relations

Inspired by @tomstuart's lovely talk on monads in Ruby, I'd like to dip our feet in with Rails on the Many monad.

Tom has gracefully permitted us to copy his work from the monads gem into Active Support as needed. The API I'm most keen to see is the one that allows us to use the Many monad with Active Record relations, like so:

Blogs.all.with_many.categories.posts.comments.split(/\s+/).values

It's a huge level up over the flat_map version:

Blogs.all.flat_map(:categories).flat_map(:posts).flat_map(:comments).split(/\s+/).values

I've wanted this for a very long time, but could think of the right way to express it. The monad is the way!

So to make this work, I'd propose that we pull in the Maybe monad into Active Support, then do a core extension for Enumerable called #with_many, and then making sure that plays nicely with the AR relations (I think it should, out of the box).

created time in 3 months

pull request commentrails/rails

Introduce delete_by and destroy_by methods to ActiveRecord::Relation

Your vote is noted. Thank you for sharing your opinion. I don't see this changing, though. I'm very happy with the API as it currently is, and I've used it a bunch in apps already. I'm going to bow out of the bikeshed now ✌️

On Mon, Dec 2, 2019 at 10:00 AM Weston Ganger notifications@github.com wrote:

There is no point to "add missing symmetry" if the methods that are added do not symmetrically match the outcome, it only symmetrically matches the method name which is ridiculous.

I vote to remove these methods. The original solution of where().destroy_all or where().delete_all is much clearer. I don't ever want to have to deal with this code in a future project.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/rails/rails/pull/35316?email_source=notifications&email_token=AAAAVNNCKNX3Q5ZC2HHG7ELQWVEMPA5CNFSM4GYFMWVKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEFULABY#issuecomment-560508935, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAAVNIVEUSKWRWISCJ4JNDQWVEMPANCNFSM4GYFMWVA .

abhaynikam

comment created time in 3 months

issue commentrails/rails

ActiveStorage: Allow access to backing file from Service API

Maybe add this to the ASt guide?

On Fri, Nov 29, 2019 at 7:32 AM Marco Colli notifications@github.com wrote:

Here's my final solution: https://stackoverflow.com/a/59107484/51387

It works great for my use case, where we have public pages with many images.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/rails/rails/issues/31419?email_source=notifications&email_token=AAAAVNJKQBIOMPUWTWLKMCTQWEYY7A5CNFSM4EH5T2D2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEFPD6UA#issuecomment-559824720, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAAVNMR3CQXPYEILDUXR6LQWEYY7ANCNFSM4EH5T2DQ .

jduff

comment created time in 3 months

pull request commentrails/rails

perform_caching config affects collection caching

Looks good to me, I think. Letting @kaspth take a look too since he actually did the implementation.

santib

comment created time in 3 months

pull request commentrails/rails

Introduce delete_by and destroy_by methods to ActiveRecord::Relation

There’s no need for a singular destroy because we are not returning any records. Unlike the finder which needs different methods for singular and plural returns.

No interest in destroy_where from my side. Syntactic sugar earns its sprinkles in large parts by the fluidity of the naming. destroy_where is an ugly method name to my eyes, breaks the link to the other _by methods, and adds nothing new not already present in the existing API.

On Nov 26, 2019, at 02:38, Leo Kiiski notifications@github.com wrote:

I agree with @adamjubert . If destroy_by is basically just a delegator to

where(*args).destroy_all then what do you call the method that delegates to

find_by(*args).destroy Can't destroy_by and destroy_where both exist?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

abhaynikam

comment created time in 3 months

pull request commentrails/rails

Introduce delete_by and destroy_by methods to ActiveRecord::Relation

To match find_by(*conditions). Also, because I think it flows much better. #delete_where is an ugly looking method to my aesthetics.

On Thu, Nov 21, 2019 at 9:04 AM Adam Jubert notifications@github.com wrote:

Is there any reason the name delete_by() was chosen as opposed to delete_where()? This nomenclature seems counterintuitive.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/rails/rails/pull/35316?email_source=notifications&email_token=AAAAVNPTCCKZ2IIBURWVCW3QU25SLA5CNFSM4GYFMWVKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEE26IEI#issuecomment-557179921, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAAVNKVXYKWRNOUPMFIIK3QU25SLANCNFSM4GYFMWVA .

abhaynikam

comment created time in 3 months

issue commentrails/rails

Firefox can cause an exception to be thrown with http basic authentication

Thanks for attempting to reproduce. I’ll verify what my details were on this happening. It’s possible that this was either on a prerelease Firefox or on the dev version. Maybe they just have a temporary bug. Will confirm.

On Oct 23, 2019, at 5:58 PM, Louis-Michel Couture notifications@github.com wrote:

Hey! I tried with Firefox 69.0.3 and 70.0, but I was not able to reproduce the issue.

Here is what I tried: gem 'rails', '~> 6.0.0' and gem 'rails', github: 'rails/rails'

I was running ruby 2.6.4

class ApplicationController < ActionController::Base http_basic_authenticate_with name: "user", password: "password" end I tried both empty fields

Authorization: Basic Og==

which decodes to :

and

Authorization: Basic YTo=

which decodes to a:

Maybe there is something else that I didn't take into account?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.

dhh

comment created time in 4 months

pull request commentrails/rails

Include rack-mini-profiler by default

Awesome! I haven't done an implementation review, but when @rafaelfranca is happy, I'm happy 😄. I think we need a clear way to communicate how to toggle this on/off etc.

schneems

comment created time in 4 months

push eventbasecamp/full_request_logger

Henrik Nyh

commit sha 848c80009d8fdf0e342e2eb40ff02d798fe16fe1

README: Fix typo

view details

David Heinemeier Hansson

commit sha c9502cacda2501bfe1cb89bd984298e7adecbbec

Merge pull request #6 from henrik/patch-1 README: Fix typo

view details

push time in 4 months

issue commentrails/rails

Add rails db:seed:replant

This is as much about being clear about your intentions as about outcomes. You shouldn't have to destroy your databases just to redo the seeds. But you're right, the outcome isn't vastly different.

On Sun, Oct 27, 2019 at 8:52 AM Rafael Masson notifications@github.com wrote:

@dhh https://github.com/dhh From what I see, db:reset has been a single-command equivalent to db:seed:replant ever since seeds were introduced https://github.com/rails/rails/commit/4932f7b38f72104819022abca0c952ba6f9888cb. Except it does drop and rebuild the schema rather than just truncating. Curious what’s the original motivation for avoiding schema rebuild? Is it just saving a few seconds?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/rails/rails/issues/34765?email_source=notifications&email_token=AAAAVNK53KTRHF3JUPQDXJDQQW2MXA5CNFSM4GLUFDO2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOECLBODI#issuecomment-546707213, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAAVNOBEOFD5YMAW7TUD2DQQW2MXANCNFSM4GLUFDOQ .

dhh

comment created time in 4 months

issue commentrails/homepage

Site is only scoring an 86 on accessibility

Please do open a PR with changes 👍

tomzmyslo

comment created time in 4 months

pull request commentrails/rails

Active storage add proxying

Starting to think that maybe the issue is trying to bake this into the model at all. Versus doing it exclusively through routes and controllers.

On Oct 20, 2019, at 20:03, Jonathan Fleckenstein notifications@github.com wrote:

@fleck commented on this pull request.

In activestorage/README.md:

+model +ruby +has_one_attached :avatar, delivery_method: :proxy + +view +ruby +user.avatar.variant(resize: "100x100").deliver(:proxy) +

+### Changing the host of proxied urls +When using the proxy option to deliver assets you can set the host. This is useful if your CDN is setup to operate on a different domain. + +```ruby +config.active_storage.delivery_methods = {

  • proxy: ActiveStorage::DeliveryMethod::Proxy.new(host: 'cdn.domain.com') +} the added complexity of this adapterized implementation is significant

@dhh a lot of the complexity comes from adding the model level API has_one_attached :avatar, delivery_method: :proxy, not the adapterized approach. I'll remove the model API and apply your other suggestions and see if we can reach an agreeable solution.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

fleck

comment created time in 4 months

push eventbasecamp/full_request_logger

David Heinemeier Hansson

commit sha 1ea87496766f75082b353ce866f2a0f3506c8f3a

Style

view details

push time in 4 months

push eventbasecamp/full_request_logger

David Heinemeier Hansson

commit sha d0085e87e0daa1dc00b86c4d6f0e91e21bf6890b

Now we have a functional index

view details

push time in 4 months

push eventbasecamp/full_request_logger

David Heinemeier Hansson

commit sha 205baf420aba61e7f0f7bfced0ec6bbfffb0b36b

Better UI ergonomics

view details

push time in 4 months

created tagbasecamp/full_request_logger

tagv0.3

Make full request logs accessible via web UI

created time in 4 months

push eventbasecamp/full_request_logger

David Heinemeier Hansson

commit sha aa023bb11a028280e9ddd49db0416d7ce5dbdbc8

Bump version

view details

push time in 4 months

push eventbasecamp/full_request_logger

David Heinemeier Hansson

commit sha 6dc2e41755336f32ca6381ecb821f2c47b961bd4

Fix call signature

view details

David Heinemeier Hansson

commit sha 7943b8936078b2d11c11c33502971f2808d2014a

Document eligibility feature

view details

push time in 4 months

push eventbasecamp/full_request_logger

David Heinemeier Hansson

commit sha 4fca4da22b0b9390bce16a19dbcf5de7e4b8b7bb

Flesh out eligibility tests

view details

David Heinemeier Hansson

commit sha 270eae37d732c24b457043dbda46f8a200708105

Delegation style

view details

push time in 4 months

push eventbasecamp/full_request_logger

David Heinemeier Hansson

commit sha 8fed8dd6037f28e5c4b78b8f266589a7ffe60c9f

Delay redis connection until first use

view details

David Heinemeier Hansson

commit sha 32cb3c05b6894f145968504273318679f9cccacd

Allow clearing current buffer or everything saved

view details

David Heinemeier Hansson

commit sha 8e8375d2e2f266418a35cf7da15ea516ea09446b

Extract middleware logic into Processor Sets us up to be selective in which requests to store requests for.

view details

David Heinemeier Hansson

commit sha 22ddb574fe0597275882f7011893e99c7f847f60

Setup structure for eligibility check

view details

push time in 4 months

push eventbasecamp/full_request_logger

David Heinemeier Hansson

commit sha 1cbecfe18afb9d11f177fa405b29b3a297528c57

Bump version for latest changes

view details

push time in 4 months

push eventbasecamp/full_request_logger

David Heinemeier Hansson

commit sha 207d296776c7f89a4f2327c55c917476ca600833

Be more explicit Flush could also just mean discard.

view details

David Heinemeier Hansson

commit sha 818ee3980b0e2f1f8b6fd1c1f62c70e894217956

Add form to lookup the request

view details

David Heinemeier Hansson

commit sha 46caff39740dd41530708df1b056c19390b8dcc4

Link back to lookup form

view details

David Heinemeier Hansson

commit sha d1ea6940f3b9f2aea585d59ceb2b9f999592780d

Style like a terminal

view details

push time in 4 months

push eventbasecamp/full_request_logger

David Heinemeier Hansson

commit sha dc5e339a9bb69610bf518947d43dda9f213724ba

Retrieving a missing request doesn't fail

view details

David Heinemeier Hansson

commit sha df69788b22734e8ed9f2cbe1e4065f748d093580

Style

view details

David Heinemeier Hansson

commit sha 761c304b5e3e2deb1bc41d5c5527a14cbf6589aa

Add light documentation

view details

push time in 4 months

push eventbasecamp/full_request_logger

David Heinemeier Hansson

commit sha a1a7bfdaea5b930b8a2b146e74c1a1d9cf3e40cc

Depend on Rails to be able to test full engine aspects

view details

David Heinemeier Hansson

commit sha 27a55b17692da5788ae7a18d1370d6dc25936499

Clearer naming

view details

David Heinemeier Hansson

commit sha 9dabe7601095f8f55a0dbcc754f1d02781d489b3

Explicit dependency

view details

David Heinemeier Hansson

commit sha 3ea894994fa8d4da1045d10f0b053c75e8dba39c

Add #reset for both testing and cleanup use

view details

David Heinemeier Hansson

commit sha 657c273af6cafa3dee67f63510e34ec895c71890

Basic tests

view details

push time in 4 months

push eventbasecamp/full_request_logger

David Heinemeier Hansson

commit sha da04fef3560e7db38820145a9262f209a5b8ce6c

Move HTTP authentication decision to runtime, since controller may be eager loaded before the configuration is ready

view details

push time in 4 months

issue openedrails/rails

Firefox can cause an exception to be thrown with http basic authentication

It seems like Firefox will send a malformed encoded Authorization header if you don't fill in username/password on the prompt. The header can look like this Authorization: Basic YTo=, which in turn produces this failure when we secure_compare:

Screen Shot 2019-10-18 at 4 13 32 PM

This doesn't seem to happen with Safari and Chrome.

created time in 4 months

Pull request review commentrails/rails

Active storage add proxying

 Variation of image attachment: <%= image_tag user.avatar.variant(resize_to_limit: [100, 100]) %> ``` +## Delivery methods+You can change the delivery method to best suit the needs of your application.++### Redirect (default)+Requests for files will redirect to a temporary service URL.++### Proxy+Files are proxied through the application server so they appear as though they're being served from your server. Useful for serving images from a CDN or HTML caching.++### Changing delivery method+globally+```ruby+config.active_storage.default_delivery_method = :proxy+```+model+```ruby+has_one_attached :avatar, delivery_method: :proxy+```+view+```ruby+user.avatar.variant(resize: "100x100").deliver(:proxy)+```++### Changing the host of proxied urls+When using the proxy option to deliver assets you can set the host. This is useful if your CDN is setup to operate on a different domain.++```ruby+config.active_storage.delivery_methods = {+  proxy: ActiveStorage::DeliveryMethod::Proxy.new(host: 'cdn.domain.com')+}

I'd like to see a concrete implementation of this idea that we find compelling enough to keep. Because the added complexity of this adapterized implementation is significant. Don't want to pay that price unless the payoff is for sure there.

fleck

comment created time in 4 months

Pull request review commentrails/rails

Active storage add proxying

 Variation of image attachment: <%= image_tag user.avatar.variant(resize_to_limit: [100, 100]) %> ``` +## Delivery methods+You can change the delivery method to best suit the needs of your application.++### Redirect (default)+Requests for files will redirect to a temporary service URL.++### Proxy+Files are proxied through the application server so they appear as though they're being served from your server. Useful for serving images from a CDN or HTML caching.++### Changing delivery method+globally+```ruby+config.active_storage.default_delivery_method = :proxy+```+model+```ruby+has_one_attached :avatar, delivery_method: :proxy+```+view+```ruby+user.avatar.variant(resize: "100x100").deliver(:proxy)+```++### Changing the host of proxied urls+When using the proxy option to deliver assets you can set the host. This is useful if your CDN is setup to operate on a different domain.++```ruby+config.active_storage.delivery_methods = {+  proxy: ActiveStorage::DeliveryMethod::Proxy.new(host: 'cdn.domain.com')+}

I think you could actually junk a lot of the changes if you just committed to two paths: redirection and proxy. Then the representation controller could redirect to either Redirection or Proxy controller, based on a top-level setting, and you wouldn't have to be passing this URL stuff around everywhere.

fleck

comment created time in 4 months

Pull request review commentrails/rails

Active storage add proxying

 module ActiveStorage    mattr_accessor :replace_on_assign_to_many, default: false +  mattr_accessor :delivery_methods,        default: {}+  mattr_accessor :default_delivery_method, default: :redirect++  mattr_accessor :proxy_urls_expire_in, default: 525600.minutes

Use a more readable time format. 525600 must be some number of hours? Or days? Use that.

fleck

comment created time in 4 months

Pull request review commentrails/rails

Active storage add proxying

 module Attached::Model       #     has_one_attached :avatar, service: :s3       #   end       #-      def has_one_attached(name, dependent: :purge_later, service: nil)+      def has_one_attached(name, dependent: :purge_later, service: nil, delivery_method: ActiveStorage.default_delivery_method)

Change kwarg to deliver_by:

fleck

comment created time in 4 months

Pull request review commentrails/rails

Active storage add proxying

 Variation of image attachment: <%= image_tag user.avatar.variant(resize_to_limit: [100, 100]) %> ``` +## Delivery methods+You can change the delivery method to best suit the needs of your application.++### Redirect (default)+Requests for files will redirect to a temporary service URL.++### Proxy+Files are proxied through the application server so they appear as though they're being served from your server. Useful for serving images from a CDN or HTML caching.++### Changing delivery method+globally+```ruby+config.active_storage.default_delivery_method = :proxy+```+model+```ruby+has_one_attached :avatar, delivery_method: :proxy+```+view+```ruby+user.avatar.variant(resize: "100x100").deliver(:proxy)+```++### Changing the host of proxied urls+When using the proxy option to deliver assets you can set the host. This is useful if your CDN is setup to operate on a different domain.++```ruby+config.active_storage.delivery_methods = {+  proxy: ActiveStorage::DeliveryMethod::Proxy.new(host: 'cdn.domain.com')+}

Do we have a lot of other ideas for delivery methods? I think going generic on this interface is complicating the feature more than its helping it. For the specific specialization of the host, that could just be a concrete feature of a proxy setup. You already have a proxy_urls_expire_in option.

I don't think this is carrying its weight.

fleck

comment created time in 4 months

Pull request review commentrails/rails

Active storage add proxying

 def #{name}=(attachable)       #     has_many_attached :photos, service: :s3       #   end       #-      def has_many_attached(name, dependent: :purge_later, service: nil)+      def has_many_attached(name, dependent: :purge_later, service: nil, delivery_method: ActiveStorage.default_delivery_method)

Same as above.

fleck

comment created time in 4 months

Pull request review commentrails/rails

Active storage add proxying

 module Attached::Model       #     has_one_attached :avatar, service: :s3       #   end       #-      def has_one_attached(name, dependent: :purge_later, service: nil)+      def has_one_attached(name, dependent: :purge_later, service: nil, delivery_method: ActiveStorage.default_delivery_method)         validate_service_configuration(name, service)          generated_association_methods.class_eval <<-CODE, __FILE__, __LINE__ + 1           def #{name}             @active_storage_attached_#{name} ||= ActiveStorage::Attached::One.new("#{name}", self)           end +          def #{name}_delivery_method

#{name}_delivers_by

fleck

comment created time in 4 months

Pull request review commentrails/rails

Active storage add proxying

 Rails.application.routes.draw do   scope ActiveStorage.routes_prefix do     get "/blobs/:signed_id/*filename" => "active_storage/blobs#show", as: :rails_service_blob+    get "/blobs_proxy/:signed_id/*filename" => "active_storage/blobs#proxy", as: :rails_blob_proxy      get "/representations/:signed_blob_id/:variation_key/*filename" => "active_storage/representations#show", as: :rails_blob_representation+    get "/representations_proxy/:signed_blob_id/:variation_key/*filename" => "active_storage/representations#proxy", as: :rails_blob_representation_proxy

/representations/proxy/:signed

fleck

comment created time in 4 months

Pull request review commentrails/rails

Active storage add proxying

 Rails.application.routes.draw do   scope ActiveStorage.routes_prefix do     get "/blobs/:signed_id/*filename" => "active_storage/blobs#show", as: :rails_service_blob+    get "/blobs_proxy/:signed_id/*filename" => "active_storage/blobs#proxy", as: :rails_blob_proxy

/blobs/proxy/:signed_id

fleck

comment created time in 4 months

Pull request review commentrails/rails

Active storage add proxying

 Variation of image attachment: <%= image_tag user.avatar.variant(resize_to_limit: [100, 100]) %> ``` +## Delivery methods+You can change the delivery method to best suit the needs of your application.++### Redirect (default)+Requests for files will redirect to a temporary service URL.++### Proxy+Files are proxied through the application server so they appear as though they're being served from your server. Useful for serving images from a CDN or HTML caching.++### Changing delivery method+globally+```ruby+config.active_storage.default_delivery_method = :proxy+```+model+```ruby+has_one_attached :avatar, delivery_method: :proxy+```+view+```ruby+user.avatar.variant(resize: "100x100").deliver(:proxy)+```++### Changing the host of proxied urls+When using the proxy option to deliver assets you can set the host. This is useful if your CDN is setup to operate on a different domain.++```ruby+config.active_storage.delivery_methods = {+  proxy: ActiveStorage::DeliveryMethod::Proxy.new(host: 'cdn.domain.com')+}

If you just go with proxy_url, in addition to service_url, I think a lot of this complicated setup goes away.

fleck

comment created time in 4 months

Pull request review commentrails/rails

Active storage add proxying

 def show     expires_in ActiveStorage.service_urls_expire_in     redirect_to @blob.url(disposition: params[:disposition])   end++  def proxy+    expires_in ActiveStorage.proxy_urls_expire_in, public: true++    response.headers["Content-Type"] = @blob.content_type+    response.headers["Content-Disposition"] = @blob.disposition(params[:disposition])++    @blob.download do |chunk|+      response.stream.write(chunk)+    end

There's too much repetition here between this controller action and the one for Representations. Extract commonality to a concern and mix into both.

fleck

comment created time in 4 months

Pull request review commentrails/rails

Active storage add proxying

 module ActiveStorage::Blob::Representable   #   # Raises ActiveStorage::InvariableError if ImageMagick cannot transform the blob. To determine whether a blob is   # variable, call ActiveStorage::Blob#variable?.-  def variant(transformations)+  def variant(transformations, delivery_method = nil)

Not liking this. It's a smell that the delivery method has to get passed around like this. Whatever the final return is, there should be a way to call a URL method on it that specifies the delivery method. Not when creating the variant or the preview.

fleck

comment created time in 4 months

Pull request review commentrails/rails

Active storage add proxying

 def purge_later     blob&.purge_later   end +  def url(override_delivery_method = record.public_send("#{name}_delivery_method"))+    blob.delivery_method_url(override_delivery_method)+  end++  def variant(transformations)+    blob.variant(transformations, record.public_send("#{name}_delivery_method"))+  end++  def preview(transformations)+    blob.preview(transformations, record.public_send("#{name}_delivery_method"))+  end

Not feeling this repetition with the dynamic delivery method invocation, nor how this is bubbled routed through the blob. What else can we do?

fleck

comment created time in 4 months

Pull request review commentrails/rails

Active storage add proxying

 def text?     content_type.start_with?("text")   end +  def disposition(disposition_override = nil)+    ActionDispatch::Http::ContentDisposition.format(+      disposition: disposition_override || "inline",+      filename: filename.sanitized+    )+  end

This doesn't feel like it quite belongs here, given that it's specific to the proxy controller, and not something intrinsic to blobs. I'd pull it into the controller instead. The object you're using is also a hint that this is a little wonky.

fleck

comment created time in 4 months

Pull request review commentrails/rails

Active storage add proxying

 def show     expires_in ActiveStorage.service_urls_expire_in     redirect_to @blob.representation(params[:variation_key]).processed.service_url(disposition: params[:disposition])   end++  def proxy

This should have its own controller. So I'd rename the existing to ActiveStorage::Representations::RedirectionController and then add ActiveStorage::Representations::ProxyController. Then you can use #show in both. And you can remap the old URL to the ServiceRedirectionController.

fleck

comment created time in 4 months

Pull request review commentrails/rails

Active storage add proxying

 def show     expires_in ActiveStorage.service_urls_expire_in     redirect_to @blob.url(disposition: params[:disposition])   end++  def proxy

Same story as with the RepresentationsController.

fleck

comment created time in 4 months

PR closed basecamp/full_request_logger

Extract logic into 'retrieve_from_redis'

Extract call to Redis into a private method 'retrieve from redis'.

+5 -1

1 comment

1 changed file

liroyleshed

pr closed time in 4 months

pull request commentbasecamp/full_request_logger

Extract logic into 'retrieve_from_redis'

Hmm, not sure I see the improvement here. The indirection doesn't add any additional domain language explanation, and the indirection is not really any shorter either.

liroyleshed

comment created time in 4 months

created tagbasecamp/full_request_logger

tagv0.1

Make full request logs accessible via web UI

created time in 5 months

issue commentbasecamp/full_request_logger

Is this gem released to rubygems.org ?

It has not yet been released. I'll cut a first release now 👍

On Tue, Oct 8, 2019 at 10:37 AM GitHub notifications@github.com wrote:

“I have rubygems.org as a source in my Gemfile :

source 'https://rubygems.org' ... gem 'full_request_logger' When trying to bundle install I got :

“Could not find gem 'full_request_logger' in any of the gem sources listed in your Gemfile.””

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or mute the thread.

thesubr00t

comment created time in 5 months

push eventbasecamp/full_request_logger

David Heinemeier Hansson

commit sha d33bc36a7a2e2e8f3fbcfe3baa288952a8dccf42

Bit more info

view details

push time in 5 months

push eventbasecamp/full_request_logger

David Heinemeier Hansson

commit sha c054d75cd9681608cbb78215a26db2d2b8286ddb

Protect request logs access behind http basic with default credentials

view details

push time in 5 months

push eventbasecamp/full_request_logger

David Heinemeier Hansson

commit sha 8a23e1916b0414ad2cd48f70dacb36c3c2f74993

Allow access to be restricted by credentials

view details

push time in 5 months

push eventbasecamp/full_request_logger

David Heinemeier Hansson

commit sha 98e62a3beb721c942cab9a693da37beddfd25d70

Allow the FRL to be disabled

view details

push time in 5 months

push eventbasecamp/full_request_logger

David Heinemeier Hansson

commit sha efa001ca4f9692659529fd435a4725c327d8dc34

Use engine configuration

view details

David Heinemeier Hansson

commit sha 9e0bdb493127ee2793093746b6b9a90fb81ed0e3

Match gem name

view details

push time in 5 months

create barnchbasecamp/full_request_logger

branch : master

created branch time in 5 months

created repositorybasecamp/full_request_logger

Make full request logs accessible via web UI

created time in 5 months

pull request commentbasecamp/policies

Add cancellation policy and clarify corresponding Terms of Service language

Good stuff. I'd also pull in something here about how we are limited in the ways we can cancel an account on someone's behalf, as in response to a support ticket, for authentication and verification reasons.

janejuenyang

comment created time in 5 months

more