There's more than one way to get mad at rails

Streamed

Good news on UK OSA - Lobsters likely exempt as email service, plus lack of jurisdiction. Major refactoring to fix N+1 queries in story tag handling PR #1475. Removed tags_a virtual attribute in favor of proper Rails associations. Cleaned up a bunch of old workarounds and test cases.

scratch


topics
  pr review
    fix indenting https://github.com/lobsters/lobsters/pull/1475
  uk osa
    https://mastodon.neilzone.co.uk/@neil/with_replies https://onlinesafetyact.co.uk
    https://mastodon.social/@cyberleagle/with_replies
    https://www.whatdotheyknow.com/request/definition_of_email_for_online_s
    https://blog.woof.group/announcements/out-of-scope-of-the-online-safety-act
    https://commonslibrary.parliament.uk/research-briefings/cdp-2025-0043/
  story tags editing


real positive about uk osa:
    https://ruby.social/@pushcx/114037503261304919

title
  there's more than one way to get mad at rails

post-stream
    

Transcripts are generated with whisperx, so they mistranscribe basically every username and technical term. They're OK but not great, advice appreciated.

Recording



03:13It's Monday. So, this is Lobster's Office Hours. What is lobsters, you ask? This is lobsters. Oh my god. Is this a flame war? I was pretty chill last night when I checked in on it. About 122 comments is a big jump from what I read last night.

...46It seems like a very fraught topic. I don't think Linux is doing itself any favors by kind of being rude as hell all the time.

04:03twitchtd good morning
And then there's lots of technical concerns that I don't know shit about. Hey, good morning, TD.

...25twitchtd your audio is doing a weird echo sound
Can you tell me if I sound better now, TD? I have... The webcam has a microphone as well as the one I actually use, and I think I forgot to... twitchtd sounds much better now
I know I forgot to mute the extra microphone, so you were probably hearing me twice with very slightly different latencies through the two paths, and definitely two different volumes, because the little cardioid mic is very nice, and the others are... the chintziest little things. Great. Thanks for highlighting. I appreciate it. All right. Looks like nothing too bad is happening here.

05:27So that is what I do regularly is kind of skim threads and make sure everyone is being reasonably kind and charitable. And if you have any questions about lobsters, the site lobsters, the moderation practices, lobsters, the code base, this is lobsters office hours. You are in the right place. You can pop up with a question at any time. I can pour tea on my lap at any time. That's not pleasant. There we go. And when I'm not doing that, answering your questions, I tend to work on the site and the code base and X, Y, and Z. So feel free to ask questions anytime. Oh, I'll do the thing of putting it in chat because if the chat isn't immediately super active.

06:37Frici watering your lap is fine, your keyboard now? that's a very sad story.
pushcx This is Lobsters office hours, https://lobste.rs - ask questions anytime
Can't even type this morning.

...46Oh, Fritchie, I had wanted to talk to you. So you caught a bug a week ago. Really, Firefox? Where the chat was missing from the stream archives. So that was a real bug, not an intentional change. I had changed this script that generates these pages to automatically fetch the chat instead of me having to download it, and I grabbed the wrong timestamp field. So all of these were getting timestamped with Unix time since the epoch, you know, one billion whatever, instead of the number of seconds from the start of the video. So my tests failed because The chats were getting rendered, but they were getting rendered, you know, 1 billion however many seconds after they should have appeared, and it wasn't so specific. So, you caught a bug. Thank you. I appreciate it.

07:57And it should all be fixed now. I haven't written the summaries and the tags for the last couple of streams. I'm behind on that, but I'll get there.

08:15Frici oh cool :)
Frici it was the no gift yes
anyway a good bug report is half of a solution it actually the fact that you named which one was the i don't remember which one of these it was i think it was the no gift was the one where it broke i immediately remembered that it was just before that stream that i had updated the script so it made it very obvious what part of code must have been broken yeah so anyways thank you for reporting that i actually had to like write a kind of cursed vim regex to read the janky csv that comes out of this thing and update just the timestamp on a couple of these because twitch only hangs on to the chat transcripts for i don't know two weeks or something And so by the time I caught the bug, there were a couple there that I couldn't download anymore from Twitch. Speaking of which, Twitch is going to delete a whole bunch of things. Let's see, where is it? pushcx https://www.engadget.com/entert…
Yeah, I think it... Ah, dead link. So if you do watch Twitch or stream on Twitch, I just saw this morning that Frici Only highlights and own uploads yes. which some streamers tend to use for free storage... instead of what they are made for.
They are saying that even if you're an affiliate or a partner, if you have highlights and clips and things, they're just going to delete them. Frici they wont delete clips though
And they basically said, Originally launched highlights drive discovery and engagement for streamers. Yeah, I don't know. Epic_Ninja_Elephant Oh hai. It's almost like Twitch isn't the future.
Frici highlights never drove any discovery NotLikeThis
I don't know if it's that gamers are a fractious sort or that Twitch hasn't maintained its relationship, but I've seen a whole bunch of very negative takes on the whole thing. Yeah.

10:35building this whole thing out. Somebody came by the last stream and asked why I don't use some free software thing that nobody has ever heard of and doesn't actually work instead of Twitch. And if they had asked it that way, the question kind of answers itself. But that is not, of course, how they phrased things. I kind of daydream about making my own... Oh, yeah. There was a pull request review. My own service, because the actual technical challenges are not so bad. It's the scale that kills you on this sort of thing.

11:26Epic_Ninja_Elephant Ah, yes, no Twitch alternatives are ready yet.
So there was this design bug reported a week or so ago that replies, if you look closely, Epic_Ninja_Elephant I'm hoping things will look different in a year.
This one is not indented correctly. There's also a... I mean, it might, but there's also the network effect of I stream on Twitch because it's what people are most likely to already have a login to. Which is mostly a spam control issue. So they pointed out that wherever you reply, there are misaligned comments. And I figured this was maybe a JavaScript bug. And this user, Tomcat, who contributed another fix, figured out what the bug was. We have a little bit of JS that kind of live inserts your comment. And it of course is very delicate to the actual markup.

12:44And the markup itself is very delicate. So let's take a look at this actual change. So we're going to grab.

13:10Wow, I don't like that. No. Now the value of this is that it throws.

...28This is such a, I realize I'm a Ruby programmer, but the fact that so much code is like, let's just barf null everywhere It drives me up the wall in Ruby and in JavaScript, which is much more brittle. So they've made a second function, but the diff is confused.

...59Create child list.

14:19Oh, that's convenient to note that these things are coupled.

...31Hmm.

...41Comment info.

...55Why did they... Add an ID.

15:11Let's see.

...18I hope the mic isn't picking it up, but my neighbors are being loud and annoying. I don't know if they are... tap dancing or moving furniture or struggling to learn to juggle bowling balls. Frici it doesn't pick them no
Noisy day in the city today. Epic_Ninja_Elephant I hear no bowling balls.
So let's see. Good. Frici however... there is a hissy pitch
I have a noise gate on the mic and it's supposed to be because the mic is very directional and pointed at my mouth. And it seems to be pretty good. So it's only annoying me.

16:09You know, I experimented on stream maybe six weeks ago, a month ago, with restructuring the comments, a hissy pitch that's Maybe the noise gate is catching all of the low frequencies of the noise and then letting through the high. All right. So let's see. This is a lot of complexity because we render a lot of complexity in our comment tree. And I experimented with rewriting the comments to grid which would drop a lot of this kind of stuff.

17:01Yeah, this is a lot of complexity.

...23Does this comments oil have any height to it?

...36No padding, no margin. But then here we add left and right margin. So I'm wondering if this, oh well, completely disappears when it doesn't have contents. And as long as it doesn't have a top or a bottom margin or padding, it would.

18:10That's fine. We've wrapped around. Okay. So this is fine. I kind of wish I had a, I guess there's this. All right. I guess that is what I want. So like, this is fine. Oh, don't hide it. This is fine, but don't hide it. This is the same change, but still don't hide it.

19:05This one. All right.

...21So what is a comment info? Why is it comment info instead of just comment? What is the value of renaming this?

...44I think they just want to be able to use comment as a variable name.

20:00Thank you.

...39So this is for platform temporary.

...52So we're kind of getting bogged down into what used to get called jQuery soup, where there's a whole bunch of JavaScript that is all very closely temporally coupled and structurally coupled by the DOM and you end up with really brittle code and that's definitely what we're seeing here and the way out of that is like throw everything out rewrite to components so at least all the code is centralized but that is not something we want to do because we want to keep the JavaScript optional.

21:54This comments subtree.

22:03Yeah.

...09So this is just when showing.

...34Yeah.

23:14Children is create child list. I don't really know why they broke this out as a separate function if they only, okay, they do call it from two places. I didn't see the other one.

...48And then lots of things are there's lots of coupling between routes and javascript that there's nothing to be done there.

24:07Well, this. tomcat is very private and hasn't said anything about who they are, but they definitely. have dug in for some really detailed fixes. Because this is very fiddly code. And they clearly have put in the work, so.

...48what's getting placed parent element i'm going to just is there a p tag i don't think anything

25:26you render back.

...35Posting reply.

26:36So it finds the then once again for comment.

...48It's searching for. What is the point? ChaelCodes Isn't that creating a p? Not querying for one?
Here. Because query strings for finding things in the page.

27:10ChaelCodes I could be mistaken.
ChaelCodes Got it!
yeah i i can see how my question could be improved no i was trying to ask why is it added for now so you're not mistaken it's just that my question was imprecise so thank you for asking So then we have, if there's so much coupling, is there just the one,

28:17I wonder if that we can flip this if.

29:21So I'm wondering about this markup. So they're getting at this form at the top of the page versus the one that gets dynamically inserted by JavaScript. And I'm wondering if there's a nicer way to detect that. Not really. This markup gets really hairy. was part of why i experimented with grid is because if i could flatten it out there would just be so much less complexity to these things of keeping track of parent elements and indenting them in the tree correctly.

30:08Why does this have to remove the comment form container?

...22Where does that come from?

...31So there's the comment box.

...49So it finds the parent of the form, which is the comment form container.

31:10And then adds these things, finds the story comments, which is going to be down the page. This is a behavior change, isn't it? So instead of rendering the comment, In place of the form, Tomcat is finding the story underscore comments that isn't present.

32:12twitchtd it is added in the pr i believe
They added this ID. That's why I don't know it. Is that up here?

...38And the story comments is going to get shoved into this instead of being... Where's the form rendered from stories show? I think here, the comment box. So they want it down to... Yeah. So the existing code is adding the comment effectively in place of this comment subtree. And actually no, probably in the contents of it. And Tom is changing it to go into this li as the first element. Where'd that go now?

33:51Create child list.

34:07If there's a children,

35:36Yeah, I don't think there's anything bad in this PR. It's just wildly complicated. But I think that's because our templating and our DOM structure is kind of wildly complicated.

36:20That's fine. This is actually a different bug fix, where if you add a comment, it doesn't twitchtd could also work on removing all js from the page and then just rerender when a comment is made
twitchtd but that's not this pr
do this stuff so they've they've really been thorough here and that's what is happening in a lot of this that would be a pretty significant functionality regression because what's happening is if you click reply on this comment you get a box right in here which is very nice because then you have the whole context if you don't have the js we have to send you to another page and it looks like a page where the parents are printed and then there's a box but that's less nice because you have to you can't see siblings and grandchildren and then you get forwarded back and there's a lot of jumping around and having anchors in your urls where You probably don't want that. The actual experience of using JS to insert the reply form and then insert the comment is quite pleasant. So I'm happy to support it for people who don't have JS on, but I don't want everyone to degrade to that UI.

38:19twitchtd got it, sounds like js is here to stay then :)
Yeah, I would like JS to be fully optional, and we're pretty close to that, but we've never intended to totally drop it. It really does make our interactive stuff much nicer, because we take a progressive enhancement view where stuff works, and we lean on the browser as much as possible, and that's part of why the site is reliable. You know, we don't download a meg of JavaScript that might load slowly or take too long to download or some random exception from some minor, you know, nine level deep dependency breaks the page.

39:40Peace.

40:01twitchtd this is the stuff the liveview has solved imo, though I'm not suggesting redoing lobsters. just mentioning in case you haven't heard of it
I don't think I know live view. twitchtd it's part of the phoenix/elixir stack, so can't work on rails
Do you have a link? Yeah, I definitely wouldn't take a dependency. Like makes the whole page a single page app and all that kind of stuff the rails has equivalents functionality in. hotwire and other stuff but. I don't know color me skeptical when it comes with a half a mega javascript it's a pretty steep price.

42:54All right. We'll see what Tom comes back with. Cool. All right. So this is moving along. I think this was the only open pull request that was looking for a review because there's some work in progress stuff happening and some experimental stuff. I don't remember where this was at. Yeah, we were kicking around whether we want this or not, because maybe we want Postgres, maybe we want SQLite. There was just an interesting thread on this on Lobster where someone wrote a blog post that was like, oh, never use SQLite on the server, but it was not a very clear blog post. A lot of it was like, If you ignore the primary benefits of SQLite, it doesn't have any benefits. Yeah, that's why you shouldn't ignore them. I don't know. And I left a big comment. We got some interesting replies. I've got to look into SQLite migrations because that sounded like a pretty significant concern. And there was just somebody made an online course called High Leverage Rails that talks about setting up sites with SQLite. And I think highly of the author, but it had nothing about migration, so too bad for me. Were there any other open issues I needed to look at? Oh, this got some activity. Hey, Peter, any chance you're here?

44:49First six duplication. Hmm.

45:20Thank you.

...56Oh my God, I can't type at this point. I guess I'm not actually physically centered on my keyboard.

46:09Let's jump over here. Where's... none of this. GitHub doesn't interlink the way I want. So anti-initializers. Part of your app code in Rails just lives in initializers because that makes sense.

...43I know I just, where did I recently?

47:02Yeah.

...48Okay.

...58All right, so that's all the open code stuff. Oh, I guess I could talk about the UK OSA some more. There hasn't been a lot of news, but there's been some interesting developments. So I had a couple of links I wanted to share. And I had wondered if DPK was going to drop by, because she often comes by on the Thursday streams. But I don't think I see her. If you're here, Daphne, say hi. pushcx https://mastodon.neilzone.co.uk… https://mastodon.social/@cyberl…
So the best places to get updates that I have seen are these two Mastodon accounts who are two lawyers in the UK. And while they are not giving anybody legal advice, they are actually writing human readable things, where Ofcom, the regulator, is definitely not. Neil here has a... pushcx https://www.whatdotheyknow.com/…
site about the online safety act that's also quite good and then there was this thread by i'll show this one that was kind of interesting so one of the one of the interesting things in the act is it says it doesn't apply to email and it says it in a way that's very interesting for lobsters because all of our user generated content is also email and in one of their statements i don't remember if this was something they wrote or in a webinar they said oh we just have a common shared definition of what email is and we don't because if you think about it for two seconds there's all kinds of complexity does email just mean smtp would gmail be counted as email because it's a web interface to email or does that include is that included in the idea of an email service so this person asked ofcom a direct question intended at getting a useful definition for actually understanding the law and so of course so there's a like throat clearing will respond to you sometime and then typical for ofcom they sent back a Well, the law doesn't define it, which is true because that's why. And then also we're not going to define it. And when we said there is a definition, we just were bullshitting and we're not going to define it at all here. We hope by a common share definition, they just refer to the fact that the word email is widespread. So we're not going to, we hope that not actually explaining or defining it clarifies the point. So this is kind of a, for Ofcom, this is an unusually good email in that they actually acknowledged that they were asked a question. They don't answer the question and you know, a shorter version of this email would have been no go fuck yourself, but they actually responded, which is unusual for them. And they, like engaged a little with the question in that they acknowledge that they've made public statements, but they don't feel like explaining them in a way that's useful for anyone who wants to comply with the law. So this is like, for them, this is a top tier answer. You know, this is their like S tier kind of answer from Ofcom. It's much better than you typically get from them where they just said, fuck off. But if they're going to say that email is used in the sense the general public uses it, that means fucking everything.

52:43And where that's interesting, the reason I talk about that, let's swap the orders around here. pushcx https://blog.woof.group/announc…
I will throw this link in the... Oh, I already threw this one in the chat. The other one is from this Mastodon service run by Afer and others, where they have made an extensive attempt to understand the Online Safety Act and whether it applies to them and how one would even comply. And it hasn't been helped by the general fact that Off coms answers are not intelligible to humans and they don't answer questions, even though they repeatedly invite questions. So what's interesting is. Their legal argument here is basically. The online safety act says that it applies to regulated services. And it has a few terms and i'm not going to bog down in the actual weeds of the text of the law, but you can kind of. guess this site is taking a nap Okay, you can read all the particular legal terms here and follow 1 million cross references. But a bunch of it hinges on do you have a significant number of users in the UK. The Act does not define what significant number means, and Ofcom refuses to explain what a significant number could mean. And I think these folks have made a pretty strong counterargument that if Ofcom examples of small services with thousands of users, if that's what you think of as small, then the very smaller numbers that Woofgroup has must not be significant. If Ofcom has never given an example of sites that have five active users in the UK or one active user in the UK, clearly those must not be significant. Yeah, it's sort of arguing from negative inference. The law has something about target markets because it's aimed at giant companies, sites that are not businesses. This is not a concept target market. Material risk of significant harmer. This one is very strange because the law invents harms and then it says, well, because we've decided to call pornography harmful, it is illegally harmful. illegal harmful content so i don't know it's very tautological the law and this mastodon instance has decided that they don't think that they have a material risk of significant harm and there's one other point that's really interesting here that you know since ofcom keeps saying if you reach out to us we want to have conversations about what applies to your service And then as I've griped, if you write to Ofcom, as I have written to Ofcom, not counting emails, just like each new attempt to actually get them to respond to stuff, I think I've tried four times to start a conversation with Ofcom. And I think once, one of those four, they actually acknowledged. They didn't answer my questions, but the other three they ignored. And then one of them They just kind of burbled some PR speak and ignored my questions. I think they have an interesting point here that if Ofcom says they will give guidance to services and then they never give guidance to me or to Wolf Group or to the million other small forums out there, Ofcom is not acting like we are a regulated service. That seems again, it's like a negative inference, but it's moderately compelling. chamlis_ exemption by modus tollens!
And maybe it's a little bit clever to say, well, if the sensor won't even bother. So this is taking a very American perspective, but Ofcom is acting as a censorship office and censoring sites and In the US tradition, we have a concept called a chilling effect, which is when a law is written vaguely and overbroad, it has a chilling effect where it freezes speech because people don't even know where the borders are. And so it is a little bit clever to say because Ofcom's actions have such a strong chilling effect that They're not serious about their role as a censor. Where, for example, they have a list of dirty words. Ofcom has published very explicit guidance on modus tollens. I've heard that phrase, but I don't know. That's one of those like affirming the predicate, refuting the consequent kind of Mode that by denying denies, denying the consequent, yeah, a deductive argument from inference. If P then Q, not Q, therefore not P. Yes, and so this is not especially robust. So p, q, not q, therefore not p. Yeah, right. So that's incomplete. Right? chamlis_ it's the inference rule for proof by contrpositive
p, t. Well, because... See, I feel like every time I read logic, it mostly makes sense, but then when I talk about it, someone points out that, you know, I have committed a Boolean fallacy that was explained in the year 1200. chamlis_ it's not constructive though
If you have, it's the proof by contrapositive. But this doesn't say that not p means not Q, right? It's just if P is a universal. It's not constructive. pushcx https://en.wikipedia.org/wiki/M…
Yeah. You are using the proper terms for what I am blindly groping towards. Here, let's throw this link in for anybody who wants to be able to click on it. Be a disjunctive syllogism. P, then Q, Q. Not P or Q. Yeah. This is the one that gets me. Okay. So yeah, if Ofcom will publish a list of dirty words, but not respond to a service, it must be that the service is not under their purview. Right? If they keep saying, we will have conversations, we will answer your questions, write to us and then they tell you, if they even bother responding, they ignore your questions, they must be saying that you are not a covered service. It's a little cutesy. I pinged Neil Brown on Mastodon this morning. I don't know what time it is in the UK, but maybe he will look in the next day or two and give his opinion. Because so there's for lobsters, there's all of these things, plus the fact that all of lobsters content is email. Because you can subscribe to a mailing list mode. And at any given time, we have a couple of dozen people subscribe to mailing list mode. So all of our user generated content is email. And then on top of that, we're not in the UK. and no one none of the censors involved have attempted to justify or provided any kind of legal rationale for their claims of extraterritorial power so what i mean by that is none neither ofcom nor any of the people involved in drafting the law nor any of the people advocating for the law no one has said ah here's the international treaty by which this UK regulator gets to enforce laws that say they cover the whole world. Why should the UK get to make laws for non-UK sites? The law has its flimsy justification that, boy, the UK is not going to like when that gets applied to them by bigger, richer countries that say, hey, UK, you can't publish illegal, harmful content about... political events or children's fiction, all these kinds of things. So I think they're going to have to back off of that ridiculous claim just as a matter of self-preservation. Because they don't want to get censored in the way that they claim the power to censor others. And, you know, I realized that governments are not especially bothered when you call them on hypocrisy, but there are a lot of practical effects that will get very bad, very fast. So I feel like maybe they won't try and do that.

01:03:58I don't know. So I'm going to chew on this and I'm really curious what Neil Brown says, but Maybe this plus email plus the jurisdictional question says I can go ahead and delete our geo block of the UK. I'm thinking about it because I really don't want to geo block the UK. pushcx https://commonslibrary.parliame…
I just don't want to be involved in a lawsuit because even winning that lawsuit internationally is ruinously expensive. so if you are in the uk there will be a westminster hall debate on the implementation of the online safety act on 26 february so that is five or six days from now depending on your time zone i looked up this guy sir jeremy wright he is in favor of the online safety act so he wants to be a censor so he's not likely to say oh This impending disaster is disastrous. Let me take responsibility for that mistake and correct it. But hey, as long as there's going to be something, if you are involved in UK politics as a, I guess you're not citizens, you're subjects, right? If this guy is a sir, you must be subjects. Whatever the term is. Go for it. Good luck. chamlis_ thought it was bold the woof article called us souls
Get involved with your government. So there's a UK OSA update. Yeah. You thought it was bold. They called you souls. Hold on. I got to pull that back up then.

01:05:56Oh, the UK is approximately 69 million souls. Yeah, I kind of don't... I think this might be because it's an American writing. We don't know what to call you. So in the US, we would say constituents. But I don't even know if the UK does have a constitution, right? chamlis_ it's blokes, the correct term is blokes
It just doesn't have a place in politics the way the US constitution does. And are you... I think the correct term is blokes. No, it's not chavs? I'm trying to think of the other... chamlis_ geezer
Epic_Ninja_Elephant lads
I am racking my brain for cute British slang that is not on the Ofcom list of naughty curse words. Geezer. Lads. There we go. feels weird to call y'all citizens and it even if subjects is the right term that feels kind of gross to use as an american because i don't know we grew up with a lot of propaganda about the american revolution and yeah i'll leave it there oh there we go yeah 69 million tossers I don't actually know if that one is vulgar.

01:07:37chamlis_ ...
Probably is. Because I'm old. I have to ask Urban Dictionary these things. Oh, it's a term for masturbation. Cool. I guess that's probably considered improper by Ofcom. I don't actually know a lot of British slang, pardon me. I am sure you are perfectly lovely... souls. Alright. So unless there is anything else to poke fun at the UK for, I'm gonna change topics. and just say oh yeah we're right on an hour so i will say that this is lobsters office hours and if you have questions about the site or the code base pop up anytime and ask or you know questions about how we're dealing with strange censorship by countries that we're not based in so on the last stream I don't know, I was yak shaving around an active record pane, and it occurred to me that maybe we can back up and change the story form enough that it doesn't have this hassle.

01:09:17So in Rails,

...25All of your data is shoved into these model classes, which are unfortunately mutable and very tightly coupled to the database. And this idea of whether data is valid is expressed only in the model. But the idea of whether a change is valid is only expressed in whether a mutating model believes its new state is correct. So it's hard to do authentication-related validations like, is this user allowed to make this change, which is part of the pain we have here because a story is only allowed to have certain tags. And so the story model now has to know who the currently authenticated user is and what change they want to make to judge if that change is permissible. So we have this pile of validations.

01:10:38And then also we have this pile of validations.

...54And then we have this method call to this check tag, which is another validation. because when you have a hammer, everything looks like a validation. And it's complicated by the fact that, well, by the way, Rails models data. So a story is the model, and then there's an association called taggings to maintain a foreign key from the story. To the tag, then the tag has some fields that we have to look at to know if the story is valid, which is strange. And then all of this gets worse because all of this is mutable state.

01:11:54And so the way our code works. Is. the form let's go look at that actually has this tags a element then there's the nice javascript interface for picking tags that i believe because it's based on putting out a select, yeah, and then multiple true. So it does work without JavaScript. It's ugly without JavaScript, but it works.

01:12:52And this tagsA, the A is a Hungarian notion for array. It's a virtual element on the story model to track what the user wants the new tags to be. And when I say new, I'm not saying the story is new, because this is also edits. It's just at the point of creation or edit. And there are a couple of potential refactorings

01:13:40I'm a little, oh, I actually had a big hassle the other day, yesterday, because I accidentally committed some of that code for disabling Grosopite and looping the taggings differently. That actually got pushed to master, because I didn't realize my working copy was in a dirty state. Whoops.

01:14:16So changing all this, I don't know that there is a better Rails idiom for allowing forms to edit associations because And I want to check on that because if there's a way to do this that would allow me to flatten out pags A and remove it as a concept, it's a lot of code churn, but the resulting code would be simpler and more Rails-y. And some of this 1 plus N issues would go away. And I wonder if there's this Rails idiom that's better because this feels a little bit like code that the original author of lobsters wrote because they were not super familiar with Rails. And Rails has changed a bit in the last, what, 13 years since the site started.

01:15:47Just checking there isn't. Yeah. Finding a form.

01:16:08So that part is fine. Ram city. collection related helpers.

...30So part of this complexity is when we have a belongs to record and you're editing the person, they just have this one city ID field rather than if you have a many,

...55I don't know if the various helpers actually handle that nicely.

01:17:21Restored attributes. associated objects. Oh yeah, that's just lead a bunch of your data. There's nothing here about as many, is there?

...46Nope. So in this case, it is not that The person, so here, for their example, the person is editing addresses that are associating to them. For us, it's we're trying to validate whether the story's objects are valid for this edit, but not let them, we're not trying to do this nested attributes thing where the user would be editing the tags via the story.

01:18:37Let's see if somebody's written this up. Yeah, so this is the past 13 years ago. This is the era that this tags a code was written. It's totally magic. Category IDs has many through, which is good.

01:19:22So it's still here. Yes, this is current. Just checking that this is current Rails, because a few things have changed in 13 years in Rails. So if we can just say other IDs.

...49Well, let's experiment.

01:20:03So instead of tags A, you would have tag IDs.

...30and then we're gonna have to jump up to the javascript because we just changed that id so this becomes from story tags a to story tags ids but then the rest of that stays the same sure let's stand up the server get logged in locally because i can start Anchoring.

01:21:16Select tag, or you can say categories instead of category IDs. All right, I'll take a look. That part about post underscore categories is the old way Rails used to format those. So let's go to localhost, test, and then submit. And I have a weird state in my Flash. All right, so we do still have a tags field. And it is now called story tags IDs. And then we have story tag IDs.

01:22:24OK, that's positive. So before I submit that, let's go look at the controller. So I'm kind of driving this from the outside. So story params, you're allowed to set tag IDs as an array. Anything else about tags A? No. All right. How many things mention tags A? bunch of specs that's frustrating because all these specs are gonna break and they cover well some of these are the ones that we want to see and then that's fine so i'm going to leave the tags a code in place and just see if i can update the form editing to use the tag IDs. And then I'll have to update this spec.

01:24:02You know, actually, as written, this code might, oh no, check tags. Check tags is going to make sure there are tags in the tags A.

...37This is going through the association, which should be getting hydrated. And then this is going through the association. Let's drop out. There's this whole marked for destruction thing.

01:25:08Yeah, that I think is a Rails feature. I want to double check that.

...35All right, so then.

...46We don't actually want to do stuff on the tagging. We want to do stuff on the tag, right? So what if I said tags.each. I have to just walk all of these.

01:26:29And then this active new record and marked for destruction should also be true of the tag model as the tagging model, which is the associated thing. And that should make prosopite happy because we're just looping these things, the tags. once instead of it's getting mad if we loop the taggings then it's gonna n plus one or one plus n the tags so that seems pretty reasonable all right let's go text one and then simple one submit can't find all tags with id zero zero zero All right, let's... So this is interesting. The tag IDs were set to the texts. Right, so Rails would like to leak primary keys and see, you know, one, two, three, instead of the two params.

01:28:12so somewhere in here it must be calling 2i on these and then compact or it's compacting out the empty string first so i don't know why the front end is sending that but

01:29:10Let's see what layer it's doing there.

...47Yeah. So it's pretty low level. So something in this code path is doing the wrong coercion where it's assuming that I want to expose the IDs. So I guess the thing to do would be to map the user input to tag objects. That could work.

01:30:43So who calls this? Create does not call this.

...56Really? We've got to do this for all of these. Yeah. So I'm going to edit story frames.

01:31:29This is going to break at a different level when the moderation gets logged, when a user edits tags or mod edits tags. It's going to print the IDs instead of the names. I guess I'll just have to deal with that.

01:32:09See, I don't want to call map, because there's a different n plus 1.

...41I think that might do it. So let's reload this. Undefined method and missed a colon. Missed it again. Couldn't find tag with ID nil. All right, so that's coming back from this.

01:33:41You see these. It's the old one. Got to make this more conspicuous.

01:34:00Oh, then what are we doing? Okay. Confused.

...23Okay, so then it turned tag IDs into the list of tags instead of the list of IDs, which could be fine. So instead of saying tag IDs, I would just say tags. because I can say others equal.

01:35:15Or I could override this IDs method, which is a little tempting.

01:36:09Got the old form, so let's load a new form.

...21Oh, broke the tomselect. Oh, because I didn't update the JavaScript for the new name.

...49So we'll say AI and art.

...57Undefined method each for nil. So who threw that exception? Description tags nil. That's interesting. It just didn't send them. Let's go back here. What was the param? So it did a post to stories with these parameters and these tags. So I must have replaced them wrong. P tags is tag find by. Yep. Didn't get that one.

01:37:48Actually, this compact isn't doing anything because findBy is forgiving. OK. Try that again. Undefined method each for an instance of tags. Who threw that? So my tags was replaced with a list of tags. No, just the one. So I see AI, but I don't see art. All right, so what did I miss? I guess I just want to say tags where is fine by as individual. OK, good.

01:38:56I'm defining that each are nil. Let's look at that log output.

01:39:07So there's my multiple tags that I wanted. Story check tags 481.

...31So the user isn't new. So this part just got skipped and it blew up here. I think we could just loop tags directly instead of walking the association like this. But why is tags nil?

...56Because this should have replaced it. I have a tags equal method to find. No. All right.

01:40:19Reload the browser off stream. InStoryModel.tags is OK. So it is a association collection proxy, which is basically an array. So that's the exact thing we expect it to be. But then line 42 is undefined method each for nil. Oh, is it? Does this accidentally define? Okay, so this defines a local variable named tags. So that's what the issue is, is we're not looping over self tags we accidentally shadowed the variable there's a little bit of hoisting that happens in ruby oh thinking about it description must contain text if no url poster that's all right so we didn't round trip the tags they didn't get correctly printed here, but that looks like it worked basically. All right. I'm going to pick up for a second and take a quick run over to the other room. I will be back in like a minute. But this actually seems like a reasonable way to cut out the complexity from check tags. And if I can drop that, we'll be in great shape. So I'll be back in a sec.

01:42:16Thank you.

01:43:49Alrighty. So this is positive. Let's go ahead and turn off the break message and see if this wants to work. So this is something about the form. I suspect that if I inspected the story model, they would be associated. They're just not getting printed correctly.

01:44:34Yeah, so there's a tag. There's so many, oh, because it has multiple attributes. So the ID, so yeah, that's the correct couple of tags. I can see AI in there and I can see art in there. It's just not being reflected on this form. So let's update the form. And I'm going to go ahead and close the JS because TomSelect is happy. I'm going to close the controller because this transformation seems correct. Hydration? I don't know what to call that. And then here, we're looping all the tags available. And then we're saying story tags. So it's this options for select that's confused because it needs to map these tags down into the values.

01:45:58That's probably it.

01:46:09Now.

...15Let's look at options for select.

...39container selected, if selected as specified, an array of values. And it wants the value or the key? The value.

01:47:11Oh, I bet pluck isn't working because it goes and hits the database. And this is a new, not instantiated object. So we have to just map the Rails objects.

...29No. Let's make sure this is not tomselect. So we have a hidden select. have the AI tag. Oh, the AI tag is selected. The accessibility tag is not. Android is not. And then if I come down a little, art should be. And art is. Okay, so this is Something happening in TomSelect because we're returning the right data. I guess I have to go back to that JS. Let's look at the console first. Maybe I got an exception. Of course not. Make sure that's not just out of date.

01:48:40What are we thinking about for so long?

...52Happened there. Okay, so that reloaded. There's no, I turned off that debug. So it's selected and tomselect ran. without any errors, but it didn't pick up the ones that were. I wonder if tomselect, I think it creates a hidden input. And because I'm reloading this page and the first one was wrong, I might just be continually reloading the page with invalid data in that hidden input. So let's just make a new one and preview it. Test three and select AI and art again, just to keep it consistent. Yes. Okay. So that's better. And if I had hit submit, I would still get this error, but my tags are there. Okay. was the hidden input thing. OK. So this is looking very good, actually. OK. So this check tags is running.

01:50:29And I don't know that these marked for destruction ones are going to be iterated over.

...46So with attributes, you have a, what does it call it? It calls it like old or original. What is it?

01:51:10Changed attributes.

...19Yeah. Yeah, go dirty.

...49Yeah, so this whole name will change. Change is applied.

01:52:21Word just doesn't appear. Thanks, Google. Let's go check what this says about active record. So we have basics, validations. I can see any of you mentioning this.

01:53:18I see this is basically what we're doing. So this role is just a string on this example, right?

...51Yeah, so it's a string on this.

01:54:01So they're referring to this underscore change method that comes out of dirty, but they're not actually describing it.

...26There is an association changed.

...36So that's belongs to. Trying to drop down to the has many.

...51No.

01:55:12Okay, so belongs to... I lost the API.

...35Lost the tab. for what the association was adding. Finder methods. Yeah, that's way too far back.

01:56:15So I sort of understand why Rails doesn't have this, because for a hasMany or hasManyThrough, they're not really attributes on the model itself that's going to be hydrated. So it would have to select all those things and even load them before the model is loaded and updated.

...53So it just doesn't have the API that this needs.

01:57:14This.

01:58:02Stop shadowing that thing. Now that can go away. That can go away. That can go away. And then this part is all fine. It's just the logging that's going to fail.

...43But this marked for destruction is never going to happen. That's just dead code. We don't need it anymore.

01:59:29okay so that part's okay it's just logging so you know that's maybe okay because the logging should be happening up in the controller anyways despite looking exactly like the example in the rails guide This, this is a thing that should not be happening down in the model.

02:00:21Yeah.

...37Those are these extra tabs.

...50Okay, that's fine. That's what I expected. And then

02:01:48Using this interface.

02:02:00You. Leave you.

...14Show and delete. date comes the one i'm just curious about okay so we've got that centralized let's go dirty called field so there was changed, but then there was. How do I see the old version. name was I just want to mirror that name.

02:03:09tags was is painful.

...46What does this other tag say? It's just virtual.

...58So I guess I will add it down here.

02:04:30So we do the assignment, story tags was, we have the values we need. For tagging changes, that's the only call to that, right?

02:05:02Yes. So this can become

02:06:30This one becomes the same thing, but on the current one.

...46Tags, map to tag. Let's see, there might be enough to make it work.

...59Typo at the end. Let's add that. Save. Should save. Good. And did that go in the moderation log? Actually, user edits don't go in the moderation log automatically. So let's use the mod edit form.

02:07:56Now that we've finally split that out, To test five now okay good I got an interesting here. what's not permitted. Oh, the MOD edit form is a different form isn't it. I sent tags ID.

02:08:32I know it's just got a different terms. All right, so let's.

...49Let's permit tags. And.

02:09:03So now I'm going to grab this method.

...19Mods are allowed to do that, so we don't need to check.

...37So if I reload, this should succeed. Expected empty string.

...56Tag expected.

02:10:05So I sent this. This update, this story params update needs to be in there too.

...23Actually, I don't. I could just swap the orders on this, can't I?

...35Yeah, so this can go up here and then don't need to save that along the way. Do the same edit here.

...52One fewer variable. New exception. Oh, because I got rid of PS, didn't I? It's just working directly on params.

02:11:21So why is there an empty string?

...32If this got replaced, but it didn't get replaced.

...45I guess I'm overwriting my change. Somehow.

02:12:26Reload off screen so I can see this. Yeah, tags did not get replaced, even though I said to replace it. So this edit just got lost somehow. So I guess I do have to do this editing in place thing.

02:13:03chamlis_ is permitting tags: [] requiring it's an empty array?
So my C got lost. So something odd happened, but I've seen a lot of odd stuff. No, it just requires that it's an array. It doesn't specify a type.

...30All right, so let's say mod edit. And I'll add back the C. And I'll save, and we'll see if that gets persisted. It got persisted, and a moderation should have been logged. And if that has the right message, did not get logged. OK. Guess I should have added some debugging.

02:14:30Yeah, there's just no insert happening there. It's looking to make sure it doesn't How to duplicate moderation, I think.

02:15:07Oh, it's this check. The editor ID is user ID. And not editor or editor equals. Yeah, so we don't. It's because I made the story. That's why it's not doing it. It's not even running the code. Let's just edit. Let's just change who owns that story.

...39Okay. So now when I reload, it'll just be some random user. Yeah, one of these test ones. So now I will mod edit this. Let's open the log in the background. I will get rid of the C tag. Equip to seven. Save. Reload here, and I should see the moderation logged. Yes. Changed last edited. That's a lot of detail and shouldn't be listed. But it did not include the actual change. All right. Layers on layers.

02:16:49Actually, why did that touch that field?

02:17:05It shouldn't have. Well, because it sort of implies that the user edited it. So that's the timestamp that's used here. Or no, it's actually not. That's the created. I guess that's fine.

...29Yeah, I'm going to... Well, the moderator edited, so I guess that's fair. All right, I'm going to leave that alone. But we don't need to print it. We do need to print the tagging changes. So this didn't throw an exception.

02:18:11It's funny, for all of this stuff around tags a, we recreated the variable there. It's a little confusing. All right. So let's edit.

...35What are you doing?

...46I think it was, yeah, I don't know why that was slow.

...57I took a long ass time, 30 seconds in active record for what?

02:19:06See, active record, 30 seconds hooked up, hat requests, milliseconds, milliseconds. Replying comments. Got to delete that view. What did this take? And then another 11 to populate the new mod table. Yeah, it's not hitting an index. All right. So let's add D. Save. I saw a ton of text fly by here on the log.

...53The old one got mutated. All right. Tags was got mutated, which means this relationship didn't get correctly duplicated. So I guess I can't dupe a relation like that or duplicated the object, but it didn't hydrate. So let's change that. And then this one has the same bug. So we'll save that.

02:20:54There we go. OK. So if I have that. Well, then I can just delete these methods. Yeah. Because they're. So.

02:22:07Need that debug. Get rid of that. Can get rid of this complicated thing, right?

...29previewTags doesn't need to exist anymore, does it? So that was just for So if I, what uses this? Because it'll be hydrated onto the model object. So if I just drop that, I think that's the only instance of it. yeah list detail uses it okay it's really nice to start getting rid of all these special cases all these workarounds This feels promising. So this will be test 9. And I will add AI and Android and then preview. And I should see must contain text. And then my preview has AI and Android listed. Good. Good. OK.

02:24:01And then instead of tagsA, I'm going to say old tag names and then new tag names.

...22This save suggested tagsA is also going to be broken, but I'm getting there. and getting there.

...44This isn't tagging changes, it's just tag changes.

02:25:07this model comment how does the comment model save its

...37Oh right, comments can't be edited. They can only be deleted by mods. So that's why this last edited ad is not also showing up in those. Okay.

02:26:08OK, this can go away. Now I just need to break all the tests. Yeah, because everything here is in spec. Suggestions, I could do suggestions. And I guess these validations preview tags, didn't I? Oh, they didn't get regenerated yet, did they?

02:27:05So look at that.

...10OK, I just scrolled up too far. That's fine. This is my changes from here. So let's do the changes in the model and then work out.

...44Okay.

02:28:26That's not user. And that's no longer true. That's the prosopite I dropped. Yeah, actually, no prosopite errors there, because we're no longer hitting the database for these.

02:29:09This one, we don't actually care if the story is, oh, this is ugly. So it's actually the association we want to check. So if the tag is no longer active, you can still, this is one of those things where because the validation happens down in the model, it has to infer the context in which it's editing. So saving a tag is valid. Saving to a tag that's inactive is invalid. But saving an old story a tag that became invalid is fine, you just can't add a new association. So if I said

02:31:06What's the ID for that tag? No.

...15That general news, we dropped that one. That was ID 8. Okay. Let's look at all the taggings. So it just went into an arbitrary place.

...34How is this not a... How did the shovel operator automatically persist? All right, hang on.

...52Yeah, it did.

02:32:05Let's just do the tagging and reload the object, clear that cache.

...25Good. So now let's reload the story. Good. And then let's mirror the way I actually want to do these things.

02:33:25See, it did immediately create that. So I guess typically in the controller would be inside a transaction. But the fact that that instantly inserts is not great for us. Because then I don't know that that tagging which hasn't even, so it hasn't done the select. So my taggings haven't been hydrated. So as soon as I go look at the taggings, then they'll get instantiated and they won't be considered new records. So what do I need to know? Actually, let me, I can do it a different way. I can just enforce it in the controller. gtfrvz timtowtdi
So we will find all the tags where that comma, you're only allowed to put on active tags. There's more than one, is that supposed to be there's more than one way to do it? There is more than one way. There's more than one way to get mad at it.

02:34:52so this is what i want to express which isn't exactly like i would like to know and throw an exception but i can't know unless i compare against the old tags okay

02:35:56Man, what a shotgun change. Changed so many files.

02:36:07So let's just say save suggested tags.

...14That part's fine. This controller is going to have to get updated.

...34Let's see if this shouldn't use inactive

02:37:17These are not apply, these are suggest.

...28They don't depend on who you are.

02:38:25This just wants to loop story.tags.

...43That's fine, actually. We'll do it to the input.

...53Throw away the blanks. That's actually dead code because they'd get ignored anyways. By where?

02:40:06Feels roughly right.

...58There's a bunch of like flattening to the string and then rehydrating, but I think it's okay. I think the right way to do this would be to refactor this so that the user is directly creating the suggested tag objects and then they're being saved rather than the story knowing how to do it. That's probably okay. Couldn't leave that alone.

02:42:21Yeah.

...50I have to run those tests at some point, but let's go do some more updates first.

02:43:33This was like, I don't mean to jinx it, but this was actually a pretty straightforward refactoring. I thought this was going to just run into some ridiculous nonsense.

02:44:20I just want to make that tags a method because there are so many places where I'm calling this. That's right. I did that wrong.

...58How many instances are there? 40. OK.

02:45:34That's a bug or two.

...47How about just this test?

02:46:03Oh, the factory. I bet it's the factory that's mad.

...15Yeah.

02:47:01What I really would like is to associate and say that we are going to create the associated record so that I can make that tag1 and tag2, which a bunch of tests assume.

...36Can't do that. It's not valid without them. I guess. Well, all right, so. Put things on screen on this tiny.

02:48:44Might be it.

...57Trying to just nibble at this and get one test working. Attribute already defined tags.

02:49:37So it's this line that's erroring. Oh, because the rest are probably also raising the exception, but we're not particular about which one we're getting.

...54So really what I want to say is... to validate the association.

02:50:32This happens indirectly.

...42So there's the error, and it's on base.

02:51:05You want to know if any of them.

...38All right, so.

02:52:34This one.

02:53:08And with each renewal.

...26So that one's fine, because now using the interface like this, Rails is going to protect me from that bug.

...42Let's just run it here individually. How rare to get to delete a test because Rails is catching a type error for me. It's not on errors, it's s.errors.

02:54:11Got empty string, which is an instance of string. So that's this one failing because I'm passing strings instead of tag objects. So oddly, once again, Rails is protecting me from a type error. And this one's going to fail. So if I say tag dot where tag colon. So that's one spec. One green dot. Hey, there we go. All right.

02:55:49So I had an interesting interaction. So I gave an update on the OSA. And since I got a green dot and I was happy, I thought, well, let's go see if Neil Brown responded to my question about the OSA. And he did. Give me just a second. How do I grab this URL? There we go. So I got my browser.

02:56:29Okay, go on. So I said, hey Neil, any thoughts on the reasoning from Wolf Group? I guess none of the last authors have even had that. So Neil says, I gave some feedback on this. I hope the OSA doesn't raise its specter for them again. I read that as Neil saying he helped draft this. So I'm going to respond in between. is posts points plus everything on lobsters is email where's that that link that i had just sent earlier in the office hours the

02:57:58Thank you.

02:58:24I'm writing a response to Neil in case you're wondering what I'm hammering away at here, but

02:59:38save i'm not i didn't bring that on screen because i was typing into mastodon and who knows what it's going to show so i can't see my reply oh mastodon

03:00:03So I had said to Neil, oh, when this was getting drafted, because I wanted to confirm that it sounds like he chipped in while it was getting written. And if so, that really increases my confidence in it, because he's just been a really clear communicator and a straight shooter. And I said, between this post's points, plus everything on the lobsters is email, given the popular understanding that web interfaces like Gmail are email. plus the lack of justification of the extraterritoriality means the lobster is in the clear in many ways independently. That's really positive. I think the... I'm going to sleep on that, but I think I can probably remove the pending geoblock because that's a... Like the UK doesn't get to make laws for us sites, the law says it doesn't apply to email the law says you know, so it doesn't apply because the UK doesn't get to make laws for the US. And even if it did the law says it doesn't apply to email and even if it did the law says it doesn't apply to things unless they have a target market which we don't or a significant number which we don't or. chamlis_ I feel like this email thing is "one weird trick" but maybe I don't understand the full justification there
risks of serious harm whatever that wording was that i don't remember because it's been a couple hours which we don't that's really good news i think that's really great actually yeah that so the email thing is edging into one weird trick but chamlis_ do upvotes, tags, flags, title changes etc all result in emails?
The law is vague on it, so where'd that... Let's see how fast I can actually find something in this mess. I don't remember if it's in this section of the law. Yeah, so... is content of, so this talks about search service, but there'll be another mention, yes. If the only user generated content enabled is one of the following kinds, contents mentioned in paragraph one, two, or three, is exempt if emails are the only user generated content other than identifying content. So identifying content means things like your profile name and your avatar. I can see, To up votes tags so tags are generated by me. up votes and flags.

03:03:13i'm not sure they meet the definition of content.

...35chamlis_ apologies it's started buffering for me and I think I missed your answer
yeah it has to be generated on the service that may be encountered i see your concern i can add emails for it but also it's so few bits that i kind of can't imagine Ofcom saying with a straight face that it's like finding out you got an upvote is going to cause a teenager to develop bulimia. Come on. Even for Ofcom, that's a stretch.

03:04:24And the thing that I like is... Oh, sorry, I don't... chamlis_ I guess title/comment edits are the more pertinent ones
chamlis_ it's better now
see any kind of warning that my connection went to hell but yeah so what i said was those various things could result in changes title and comment edits Title and comment edits already get emailed because the emails happen on a delay specifically to account for that. So that's mail new activity. chamlis_ ahh
So it actually won't email things if they've been edited. It requires that some time passes. There's a similar logic for, I don't remember if what I just showed was comments or stories, but it's the same thing, the same logic on both. And so then to your other point of upvotes and flags, number one, I could have them send emails, ideally not by default, because that would be a pile, but I could just include them in the existing emails, which are already on a bit of a time delay. And in any case, it's very hard for me, even with how malicious Ofcom has been, to imagine that they can say with a straight face that like a teenager getting an upvote caused them to develop bulimia and donate money to ISIS and all of their other censorious farms. chamlis_ I guess don't feel like you have to jump through hoops to sate me; I'm really just writing legal fanfiction here
so i feel pretty okay with the amount you know because it's such a narrow channel that like that's user generated content really so i share your your concern about one weird trick and i've said that kind of thing a bunch but their answer to what's email is that whatever people call email is email. And we've been email in exactly that way for ages. And its definition of email explicitly says, I don't remember the wording, but it says something to the effect of even when there's software involved. So like, The user does not have to manually bit bash their email into telnet if they use outlook or if they use gmail. that's still considered to be email and in the same way like lobsters is the interface gmail is the interface so that part is actually very straightforward. I don't feel like I have to jump through hoops. I feel like this is very worthwhile to think through out loud because Ofcom's threats are so big that it's worth a little reflection. Oh, and Kyle just popped up. We started bouncing this back and forth after Rachel's small services session.

03:08:27chamlis_ this exemption is strange though if it means all evil sites could move to a mailing list
yeah oh he's gonna is i think that's his personal blog so i'm gonna load that off stream because i know wolf group includes a substantial amount of explicit yeah okay this is just his blog if this was a more personal site that included some of the same materials as on wolf group i didn't want to throw that up on stream

03:09:04Oh, the OSA is not written for evil sites. Like, it's just not sophisticated. And to define evil a little, it's really not written for malicious interpretation, and that's going to include sophisticated lawyering by exactly the kind of huge social networks that it was written to target they're going to run rings around it just having worked with very competent lawyers before and seeing how they think no this is not at all it is a failure on every level the osa okay

03:10:05Yeah. So for anybody who doesn't get why he's going to block the UK on his personal blog, it's because he has a comment section and the OSA says, if the only user generated content is people replying to your blog or your product posts or your journalism, you're fine. You're exempt. but it is not at all clear about comments on comments. So someone can post a comment, you know, so Alice can reply to his blog post and say, great blog post. And then Bob could reply to Alice and say, Alice, you're a jerk. Well, that would be potentially that would bring Bob's comment back into scope. And then Bob's comment would drag the entire thing onto the OSA. And people have asked Ofcom, hey, how about this comments on comments thing? And they've said, fucked if we know, we'll never give you a straight answer. And I am, obviously I'm abbreviating their answer slightly because they took a lot more words to say less than that. But that was the thrust, the main gist of their conversation. So it's unrelated to all this nonsense. pushcx https://en.wikipedia.org/wiki/A…
I don't have the keyboard shortcut in this browser. But there is a book series called the Aubrey Maturin series. And I just started my second read of it. And it is very British. it is set in the age of sale in the what must it be early 1800s mostly and it's wonderful there are 20 books and they're a bunch of so there's a british sea captain and he sails around and he fights the french and the spanish and the pirates and the everybody and it's about the captain and the doctor primarily Although over the course of 20 books, as you can imagine, there are plenty of other characters. And I guess I have had a... vinitkme Hello, Hello!
This is my exposure to British culture lately. vinitkme How are you doing?
I am just a third of the way into the second book. If anybody's curious to read it, the first one goes a little hard on the nautical detail. to establish credibility, but then it settles into something quite nice. Hey, Vinit. Nice to see you. Well, you know, with a giant shotgun refactory actually going smoothly and a credible path out from the threats of the UK Online Safety Act, I'm feeling pretty good.

03:13:35chamlis_ did wallace and gromit make its way across the atlantic? when I think of quintessentially british things that's up there
vinitkme Your vim Setup reminds me to Gary Berndhardt
did wallace and gromit cross the atlantic yes oh yeah so i know i know wallace and gromit have had some recent stuff that i haven't seen for a minute but they are justifiably famous and both over here in the states and in my household i think wallace and gromit is pretty great it's been a minute since i've watched very cute stuff

03:14:06Oh, so my Vim setup is not really inspired by Gary Bernhardt, because it looked like this before I started seeing his videos. But I do think really highly of his videos and his talks. So right on. A lot of what vinitkme Nah, I don't mean you are inspired. Yours is as simple as him and very efficient.
Why this is plain is because I just wanted to strip away all of the distractions of stuff I don't care about. Like this should have no spell set in this. We don't need that red there. Yeah. There's kind of a trade-off between expressiveness or obviousness and efficiency where new users want to have graphics and buttons and visible state and tool tips. And then power users want to have absolutely no distractions. vinitkme The better you get at Vim, the leaner and meaner your Vim gets
And for a long time on computers, you know, up until, I don't know, call it 95, early 90s in some case, computers were expensive enough and people could be expected to train on them. So everything was power user interfaces. And I started back then and kind of never stopped. So I've even had that in, you know, Firefox where I've turned off all of the buttons I never click. All right. So does this, I got a green dot out of this test. Good. So now How many, if I refresh my search, I have 26 hits for tags A. Okay, that's not so bad. So I'm at like three hours, 15 minutes, which is running a little long, but I think I feel pretty good about working through these to maybe finish the refactoring. I probably won't deploy it. But let's see if I can get to a green test suite, at least at the model level.

03:16:52Let me actually put this in here.

03:17:07Grab that URL. I think I said something like, to respond to GTFRVZ, something like that.

...46This just goes away. Because this is sort of testing the builder. And now we're using the rails feature. Yeah. This is the default stuff so what i want to say so what i want is to create a story with particular tags and i'm not sure that the factory bot interface is that expressive let's find out

03:18:50And if I say. And. See, I expected I would get tripped up by like 100 of these kinds of things when I started this refactor. And it was going to be up in the active record. Attribute already defined tags. Yeah.

03:19:40So this is a factory bot thing.

...59See. It says call create and then do this. But the problem I have is that these the user would not be considered valid without the associations.

03:20:32Maybe the way to do it would be to say, build stubbed and create user has posts, association post.

03:21:17So what if I said, let's create a, instead of creating a tag1 and tag2, we'll create a, well, in addition to, I should say,

03:22:29then every story then this association how does this even run if this is in the after how do any of these run

03:23:11Where's this association? Does the association method take a block?

...47To always make an additional object, it takes a mandatory name and option. The options are zero more trait names.

03:24:32So override attributes on associations. So this would say it has an author. Here's the block I'm looking for. All right, so what if I say just tags is

03:25:05That's what I've said here.

...31So this one I expect to run because I'm passing the tag objects. Controller didn't say if tags was. So that's fine. That's the interface I've defined. So I guess I could put this into s.tags equals. and probably should.

03:26:09Think about that one.

...19OK, and if I said. I just want to make sure that this runs without an exception. tag has already been taken? Oh, it's trying to create another tag object instead of associating to the one that exists.

03:27:20OK. All right.

...28So that's fine. Now I can create stories that have either a placeholder tag or I can specify what I want. OK. All right. So this is just a repeat of the previous, because also Rails is already handling this association.

03:28:32Suggested tags. twitchtd any chance newest and top can be moved to top level links next to Active & Recent?
Yeah, it's exactly the string I just That's fine. That's that dancing I was talking about, but that's fine.

03:29:21Put newest and top up here. It's getting a little pushcx https://github.com/lobsters/lob…
busy maybe so the considerations are that's kind of a lot to squeeze up there but then also there's it's especially a lot on mobile i don't know it could be there is an open issue about the twitchtd need a hamburger menu for mobile XD
So if you haven't seen this, there is a... Yeah, I tried to avoid having a hamburger menu. I'm not sure that was successful, but this section is scrollable, which is pretty easy to swipe.

03:30:32twitchtd I always look at newest
twitchtd yes :)
twitchtd I like the line
anyways can you tell me some more about why you want to put them there up in the top is it just that's your favorite way to browse the site or you think it would be better if everybody used it you always look at newest newest because it has the line on it yeah yeah same

03:31:12So it's especially slow because there's no caching in local dev, but I feel like maybe the fix is to make those page loads instant, because then it wouldn't feel bad that they're two clicks. If I could get that set, I don't know.

...50twitchtd not a big deal, just wanted to run that by you
Yeah. Why don't you take a look at that GitHub issue? Because it's got a whole bunch of brain dump on design. Yeah. And also what my thoughts are on why I put these particular links in the top nav and not others. It also links to when I redesigned the top nav. It's got to be a couple of years ago now. So there is all the detail you could possibly want. So I see why newest, because it's nice for that feeling that you have seen everything. And I definitely have that like gotta catch them all feeling, not just because I'm a moderator, but that's why I read like HCKR news instead of the Hacker News front page.

03:32:46pushcx https://hckrnews.com/
So this page, which works pretty similar to slash newest. And then could you talk about why you are wanting slash top up in the top nav?

03:33:31twitchtd I don't use top but it just feels like a 2nd submenu for 1 link is overkill
Fair.

...37Yeah, so... I've sort of thought that upvoted stories should probably go into here if you're logged in. It's not very discoverable. I think it only shows up under your settings. And so lots of people don't know it's there. But that would only be for users, not for visitors.

03:34:28Yeah, I don't know. I'm not sure how to make that decision. So if you look at that GitHub issue I mentioned, there's a bunch of I kind of eyeballed things. twitchtd will take a look, ty
I don't have any super confident answers on this stuff, but maybe there are analytics we could do to figure out what we should be guiding new users towards.

03:35:06I guess my only two opinions, three opinions are number one, I'm automatically a little skeptical about UI change because nobody likes UI change and it disrupts everybody's muscle memory. So number two, I really want to keep active next to the logo because the beating heart of the site twitchtd active makes sense to be #1
is discussions and having these stories where there are active discussions or some other way of pushing people like it almost doesn't have to be slash active as long as it satisfies that need of go find conversations to participate in what are people talking about right now on local hopes this is going to be nothing i don't know why i clicked and then third This is just generally all a little bit fugly because I'm not a designer and I don't really have any principle decision making behind any of it. So I am open to change all of it, but it just helps a lot to have some amount of justification for it. So we can look at logs or we can run a user survey or we can throw up a meta thread, but it would help a lot if somebody who wants to change navigation had some kind of cohesive framework for thinking about it so that I could feel like we were doing less of just fucking winging it I hope that makes sense it's not I don't want to put a giant burden on someone contributing just the thing that we need is a way to make a decision less than well let's just paint the bike shed my favorite color because twitchtd true, maybe this is just bikeshedding :)
twitchtd I don't like the 2 clicks to newest is all
way we got the top nav we did is very much i painted the bike shed the color i liked and i will admit that that is exactly what i did and i don't want to do it over and over yeah there's nothing automatically bad about it except for point one of well then it's churning on the thing that we don't like or churning on the thing that is familiar to people and that's really disruptive and annoying And I don't want to change nav and just bug people unless there's going to be some feeling that it's going to be an improvement.

03:38:06These specs are so hairy.

03:39:04Preview tags. Oh, this goes away. I deleted that code. You know it's a good refactor when you get to delete a bunch of tests. Because just the whole surface area got smaller.

...33It's intending funny because I'm doing that.

...54Oh, okay. Is that all the instances of tags? All right. Let's see if anything. wants to run like I'm assuming there's typos and stuff so I'm gonna start from just the story spec and then just the tag spec and then all the model specs and then everything okay okay four four is not so bad all right so here's that interface again

03:40:32controller that's a legit bug the controller was supposed to set that and didn't so

03:41:05So let's go ahead and have it say. And actually, it doesn't need to happen there. It only needs to happen if we're actually going to change any final tags. Except I already have that code down here and it didn't run. if we got that exception. So save suggested. Oh, save suggested title. I put it here. I didn't put it in the title change, which has the same issue. All right. That might be two out of these four.

03:42:06twitchtd ya
know td if you don't like two clicks to newest you could bookmark slash newest how do you usually navigate to the site do you just start typing lo and then it auto completes yeah so i don't know the mobile browser interfaces but on desktop if you go like here and then you hold shift delete you can delete entries i do that all the time on my browser to make sure that like slash newest is the first thing there's probably a version of that on mobile or like a you could clear site data for lobsters and then manually load newest you know type the full url so the the home page doesn't get in there and then you would have That'd be the most popular autocomplete, because it's the one you had visited most. Two is greater than zero. So story spec, let's go 277. So this is me exercising story the same way controller does.

03:43:49Hey. All right, let's print all the model specs.

03:44:18Okay. So it's all search. So that could just be something about tag. Type tags instead of tagged. Yep. That's Rails.

...51It looks like there's one or two failures there.

03:45:05Okay, so that's good now. And then the story, let's do story spec that I already ran because I must have broken something there.

...20no that's green it's only when i fit do all the models that's going to be a fun one let's do this that one's also green all right let's run all the models and see if they'll start failing i have mostly avoided this on lobsters where we don't have a lot of Interdependent tests and we don't have this kind of thing of you run a test in a sweet and it fails sometimes alright, I must have just had a typo or something. I am suspicious and untrusting we'll continue. it's from the whole sweet.

03:46:15Not so bad. Getting a little worse. I mean, when these clump up, it's usually there's like one change I have to make and all of those will go green. So this feels like it's probably three or four. Why did we stop? Hello? RSpec? You stopped running. One of my specs takes 40 minutes. Okay, so there's some kind of accidental infinite loop.

03:47:04Alright, I don't know which spec is failing. Alright, so it's probably not a model spec.

...29let's see if it's a slow spec oh there's nothing in there i thought i had routing requests and features are the two big directories here so i'm kind of nibbling around the edges real quick okay

03:48:37So it'll be one of these requests or features that hangs. And then, all right, so it's requests. So let me go do, oh, are there still controller specs here? I'm going to do the other one and then come back for the hang because it feels like the kind of thing that's just going to disappear if I sort out what's what.

03:49:09Okay. Good. All right. User thread spec 58. I guess I edited a thread. This is me being a little lazy. So if I said story equals, let's create a story in the state we want rather than mutate to get there.

03:50:29Oh, I'm mutating the story because you can't write a comment on a story that's deleted. That's why.

03:51:01So that was 46, 58. Do the same thing here.

...16Let's see if those two want to pass.

...23There's one on 22. That's probably going to be the same pattern. 54 is still broken.

...51Something went deleted? Oh, because I renamed this. OK.

03:52:10okay and then there's something on the home page i saw the word tag go by so not surprising oh i bet i bet these Category Create. No, I updated these. All right. Well, let's look at what these errors are. We'll go one at a time.

...57Unknown column A1. Oh, I didn't name that. That's probably all it is. It's a bad edit. I don't want to fix that spec. Good. So that's all of spec features. And then I'll have to get into whatever spec requests is hanging. I think there's some way to get this to print. incrementally instead of just when it's done. All right. Order. Maybe the backtrace will do it. That would probably be good enough. Well, let's just say

03:54:17I'll fail fast, because there was a chunk where some failed, and then a gap, and then two failed, and then the one hung. So I can get some of these. User votes on a merge story does nothing when upvoting merged story. Expect nil. Oh, that's an interesting. So it's not so obvious. What spec was that? Requests merge line 27. That's interesting. So there's nothing here explicitly about tags.

03:55:16So if you upvote, you post to the upvote action, find the story. If it's merged, you get back a 400. Here, I can just run that one directly.

...59200 okay why doesn't this have them merged into id set so this says The mod should go ahead and merge them. I wonder if this is failing. Because rather than just create the data, I do vaguely remember writing this test. I didn't have a lot of faith in just directly setting the data, and I didn't want to couple to that. Come on.

03:57:05They're getting back a 200, which is probably wrong. Yeah, problems with the following fields must have at least one non tag. If there aren't any, it doesn't belong here. Where's the list of tags?

...34tag place folder, not selected, not selected, not selected. How did we get a tag persisted? Like I could just fix these by

03:58:00saying this should have emerged story ID. Story. All right, and then this just becomes.

...21But if it's failing here.

...29It's the mod stories controller. Oh, I bet the form didn't get updated because it's a different one.

...48Yes. Something about tags here. No, this just renders the other one. Oh, it should work then.

03:59:03On I did treat that all right let's. gives me a little bit of fear that if I do this, the test is going to pass and then it's actually some kind of breakage that i'm going to find in prod yeah. Something about merging stories.

...29This isn't tags it's. Story tags, isn't it? Let's put that back, that back, and see if these still run. Like it's an accidental test. And find method empty for new.

04:00:29parameters reason cuz. Oh, I see. So this No, it's a bug in the test. The test was not sending back all of the form fields. Just the two that it was trying to edit.

...54And then this was looking up the tags.

04:01:02Yeah, mods are allowed to do that. Okay. So this is just, this part is wrong. So let's put all that back.

...23Great. So I think that spec is fine.

...41oh four hours i'm running long very long the if anybody has any last questions about the site of the code base now is a great time to ask it because i'm on the home stretch of fixing these tests and this is lobsters office hours and the refactoring is oh i forgot to put on the footer darn it didn't follow my own checklist

04:02:12So that's probably the same bug that the patch has to pass the tags back up.

...34So what line is failing? 15? No, that's the test, 23.

...56How did this ever pass? Because it shouldn't be able to... Maybe the spec was allowing it to delete the...

04:03:50I expected a redirect, but it was 200. So it's probably, honestly, I expect that it's failing because I didn't set a moderation reason. How did this ever work?

04:04:35Problems with the following fields must have one tag if no tags apply. Oh, I didn't put this in the right place.

04:05:01Oh man, standard RB, that's rough. How about that? Okay.

...20Permitted query or form parameter. Which one?

...41to know which one was unpermitted and why. Because this is, this is just about it.

04:06:23Where's my debugging?

...29I guess I got it from this. I feel like I'm staring at it. Did this slip out of sync? Tags versus tag ID.

...54this not have the word tag? No, because this renders that sub form.

04:07:29And I didn't create the variable yet.

...41Because I figured it's that require throwing the 400. Tags placeholder. So that looks totally valid.

...58Tags gets rewritten to be the tag objects.

04:08:12No, this has got to be story tags. Because when it's printed, it's story tags. How does that work on that regular one? It's possible the regular one isn't tested and it's broken now.

...39It's a string. It's a string instead of an array. Put it back.

...56Yeah, it's that join. The join was invalid.

04:09:04So many type errors. Okay, so that's... A kind of progress.

...28Sarah flash in all of this. That's the nav.

...43No.

...53So who's failing now? Which line? 46. That's a new one.

04:10:32Now we're on to the next spec. So yeah, something about this tweak made this.

...46Well, if we don't pass it, it doesn't get updated. And as long as it's valid before, it stays valid after. Yeah, actually, instead of passing empty array, it should grab the story object's existing tags. Yeah, that's what all this pain is.

04:11:23And then this is also going to be true of the other stories controller.

04:12:08okay so there's that let's see if all the requests want to run because that may have fixed the hang too whatever it was mystery okay it did fix the hang and now story spec which i'm gonna just go out on a limb and guess this is Got a bunch of pieces of code that edit stories in it. Yep.

04:13:07It might be everything. No, not quite. Undefined method tags for nil. Who's failing? Line. Oh, this new one. The story object isn't loaded yet.

...46How is it not loaded by the time this gets called? Because I call it right there. So preview does that, who else?

04:14:06Just preview. Is that actually a tested preview? No.

...27And then this calls it before it tries to instantiate an object.

...42So that might be all of those. All of this was to remove a one plus N. I must have inserted a puts here somewhere. I'm getting a blank line. Ooh, there's my hang.

04:15:07And I'm very suspicious of stories spec because it is the one that failed before.

...19So it runs one spec and fails.

...30So let's get into the hang, and then I'll Control-C out so I can see the trace back. It should be the second spec. They run in order, but guess not. All right.

...49So here's one spec. Here's a second spec.

...59It should be params story URL. Say params.dig so that we just preserve nils all along if story isn't present. See if that was it.

04:16:24Apparently it was. Didn't like something about that.

...43So let's see that without the big back trace.

...50The error message is wrong.

04:17:07Oh, no, this should be URL. Check URL to, I was just sort of assuming it was using the same story form, but it's its own standalone endpoint. In which case, why would we call update story attributes? I must have just pasted it in. Yep.

...35So what did that say?

...46it didn't have it at all which is fine because it doesn't need it all right so that's that's that whole hassle this should be great please be great or hang you could just hang

04:18:17So it's this spec hanging, right?

...32I see that story.new in the action, and I wonder if it's still hanging.

...59I wonder if it's something in this check tags that I just wrote. Because this has a couple of loops, but it doesn't have any nexts or breaks or anything like that. No.

04:20:23Which one of these

04:21:01Huh. Be successful, Hanks? That sounds like me.

...19This from last year that's open, going to Rails.

...32Have HTTP status OK. Also using SuperDiff. Am I using SuperDiff, Jim? Yes, I am. OK, so there's HTTP status 200. So there's, and it instantly exited. No, I have a typo.

04:22:22Still hanging. But if that was the second one, and it is,

...42okay so whatever that bug is i'm seeing it so that was lucky that i found that so let's

04:23:25Now, at least this file should run. I should get a bunch of errors. Good. Now, you know, not great to get errors, but it beats weird-ass hangs.

...53So I'm just going to pick one of these. Let's go with this one.

04:24:15I think I must have had a call to story parameters in the old version, didn't I? Yeah, so this is the error I should have seen. This test was wrong. Should be one fewer error or failure. Good. And let's go up to 19. So if we call check URL dupe. Wait, do we expect story or story URL?

04:25:00This looks like we're saying story URL.

...10And that would be why these failed.

...19So we're not getting that extra exception. First one says line 25. So we're getting a success.

...54This doesn't apply the URL at all. Hang on, I made a bad edit to check URL dupe. That's what's happening here.

04:26:36So this said story attribute to story params, it does all that when it should just say.

04:27:08It's one of those signs that the model is not getting used super well, or it's not factored well. Because that's not just a standalone method, it's on the model. That's a different spec failing. So that's 59.

...57I expected to have the title. Didn't have a description. It had title of story, title four. Why didn't it say some other title? Return similar story matching URL. This spec is also wrong. The returned story was pulling this instead of actually printing JSON about the story it found. Well, I guess the title could be there. All right.

04:28:59So then if this was...

04:29:13It's weird to return the story at all, but I don't know if part of the front end is depending on it. OK.

...27Is that everybody? Is everybody happy? You know, I saw homepage spec fail in there. It wasn't until a couple of years ago that I even created the homepage spec. So I had actually broken the root path once in production because we had not even a smoke test for it. That felt a little embarrassing. There we go. I think that's the end of this refactor.

04:30:08No warnings, wow. Is that a big enough refactor? How confident do I feel if I deploy that? Oh man, not super confident. There's a lot of code that just changed.

...34And I've seen it. And I played with it. But man, what a shotgun debugging. It almost wasn't a way to... I mean, I could have left the story tags A in place and then done these one at a time-ish. No, the stuff around logging the moderation would have had to update immediately or know that there were two code paths. There's no smaller way to have done this, really.

04:31:06Oh, there's that extra puts.

...51Okay, so there's the end of that. I'm going to, yeah, I can push that up to master. I'm going to take a break, go get some lunch. Maybe I won't even deploy it today. Oh God, another one. Busy week for Dependabot.

04:32:18It's... Oh, it's the one I already did.

...28So I had bumped Nokogiri for a dependency thing. And then even after bumping, Dependabot was like, oh no, it's still an error. So I think something odd happened about how Dependabot recognizes Nokogiri or how they packaged libxml2, OK. Oh, maybe it's different. The CVE is in Nokogiri, but it was in the dependency. Yeah, OK.

04:33:19This doesn't apply to us. So I'm just going to go ahead and dismiss this.

...40So something weird is happening with Nokogiri and Dependabot the last couple of days that I got the warning about something that won't go away. All right. Well, for anybody still listening, thanks for hanging out with me. This has been Lobster's Office Hours, where we chatted about a bunch of stuff. We maybe got some very good clear path out of the censorship of the UK OSA that doesn't involve blocking the UK to avoid that dumb fight. and then did a big refactoring of some very old code and you know i actually feel pretty good about this that there was enough tests that i've built up over the years because almost all of these tests were mine that i got rid of that one plus n all right Good times. Well, thanks for hanging out. The next scheduled stream is what, Monday? Monday, 2 p.m. Chicago time. Different times in other lesser time zones. And thanks for hanging out with me. Frici productive times 👋
Feel free to drop in or email me or DM me on the site or DM me on Blue Sky or otherwise reach out anytime you have questions. Take care, folks. Oh, yeah. Thanks again, Freachy. I appreciate it.