I would cry if it said lobsters

Streamed

PR review of CSP reporting disabling. Vibecoding spam in GitHub issues. Self-hosting code forges vs. GitHubโ€™s network effects. Bidirectional sync for migrating away from GitHub, which is not planned for Lobsters. Refactoring mod controllers into mod/. Convention of โ€˜moderatorโ€™ for user-facing; โ€˜modโ€™ for mods themselves. Idea for ModActivity model to combine Notes + Moderations. Fixing fake data task bugs.

scratch


topics
  PR review
    disable CSP reporting https://github.com/lobsters/lobsters/pull/1696
  issues
    vibecoding spam https://github.com/lobsters/lobsters/issues/1686
    probable slop comment
    self-hosting a code forge to avoid spam
      network effects
      huge loss of contributors if you do a flag day
      bidirectional sync to migrate
      preferably something useful in the repo, avoid a new silo's vendor lock-in
  mod controller - finish moving controllers into subdir
  convention: 'moderator' for user-facing; 'mod' for mods themselves
  idea: ModActivity model
    Notification combines Message and Comment
    use the Notification model to combine Notes + Moderations
    would let me combine tables on user profiles, easier to see history
    also the single-story modlog table could include notes
  mod work queue


title

post-stream
  stream notes about raids
    

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

Recording



01:30because or maybe i'll celebrate it after i should actually you know tweet it beforehand yeah i'll be able to make next monday that's and then after monday i'm gonna miss what is that one two maybe three we'll see anyways so this is lobsters here that you see on screen You don't have to explain why you posted something.

02:07This is one of those where it's my job to be the no fun police.

...22So anyways, I moderate the site and just kind of So let's say merging.

03:23All right, so nudge that along. A little demonstration of story merging, as you can see there.

...37easeout good morning to you
Curious about this one about live coding, because, you know, that's what I do when folks aren't asking questions about lobsters. Ah, hey, Ezell. Welcome back. So let's throw the message in the chat.

04:07pushcx This is Lobsters office hours, ask questions about the community or codebase anytime!
All right. You know, they talk about the stress of live coding with folks watching you, especially evaluating you. And live streaming is certainly a step down from interviewing in terms of stress because, you know, in an interview, someone is directly evaluating you. That's the point of it. In live streaming, they're just evaluating you for funsies. The first couple of times I streamed, I was just done for the day. If you've ever given a conference talk, you probably know the feeling. ChaelCodes Hi!
You come off stage, and you answer a couple of questions, and then you fall asleep for 12 hours. But at this point, it's pretty comfortable. I guess there's a familiarity. ChaelCodes Yup!
Ah, speaking of people who are familiar with streaming, back to it, Jill. Twitch told me you did a shout out, but I don't know what that is. But thanks, I think. I bookmarked the stream archive so I could go find it by timestamp, but then I got distracted. So we'll have PR review. ChaelCodes It's an encouragement for people to follow you!
I'm sure we got issues. And then otherwise, I was going to work on... ChaelCodes Typically paired with a mention of a streamer
ChaelCodes Thanks!!
mod work queue because i discussed it here on stream a week or two ago with chambliss when i tried to sucker her into it ah well thank you if anybody doesn't know let's see what's ah there's a command for channel codes there's one in any case Yeah, I think you are like 10 times more popular on Twitch than I am, so I don't know that it matters, but for what it's worth. And if you're going to stream today, I plan to run my usual about three hours to noon central time. I'm happy to throw to you. Raid. ChaelCodes I agree that time lets you build up the stamina for longer streams.
I should put that in the stream notes.

06:39ChaelCodes Yeah! I go live in an hour.
Because I've mentioned it a couple of times to folks who've mentioned that they stream. Yeah, there's also just kind of the fear that, oh, an hour. Well, I was going to run longer than that, even though I have a bunch of stuff to do. ChaelCodes Yes!
I was pretty sure I'll run longer. But you know what? You'll be live after I'm done. So yeah, it works out. Yeah. ChaelCodes Thank you.
Well, I'll throw to you because you're going to go for more than two hours, right? You do longer streams. Cool. ChaelCodes Last week was 6.
then let's try to make sure I remember. All right, so there's nothing new in the pull requests, although this one got a little activity of Kay Connor helping with the typo. Oh, I still have to re-approve that. I already read the diff, so that's not me giving away our attributes and secrets. And then I merged ChaelCodes 6 hours
think two prs off stream because they were small no just one i guess so we have talked about the disabled csp reporting last week was what six viewers oh that's smaller than me but i thought you have subscribers followers I thought you had a ton of those. But you're coming off a long break. Yeah, you got to rebuild. Oh, six hours. Yeah, that's certainly longer than me. I don't have that kind of stamina. All right. So Chamelis, I don't know if you're here, but this is a long-running project that Chamelis has worked on for improving site security to prevent cross-site scripting attacks and CSRF attacks. chamlis_ hi! thanks for merging it
And we've never worried too much about those because we have a fairly limited attack surface. But what we do have is kind of the perfect breeding ground of things like about text that has markdown and common text and story URLs. And when you are sharing, you know, the whole point of the site is to share user content. You have to worry at least a bit about CSRF stuff. So The reporting function generated a hell of a lot of false alarms. It's a shame Telebugs doesn't have... I understand why it doesn't have weird censoring stuff for all the PII in there, because otherwise I would just give you access to it. At this point, Chambliss, you fixed so many bugs. twitchtd morning
But it was drowning in thousands of CSP reports a day, all of them false alarms, because the user... has a plugin that inserts a script tag, or overrides the font, or uses a bookmarklet probably. Hey, TD, welcome. So I got this merged, and I am very pleased to say that we have stopped getting buried in false alarms. I'm going to double check the thing off screen. ChaelCodes Yay!
chamlis_ I'm shocked nobody has reported that something broke
there's a little sidebar toggle yeah so all right light mode warning because this browser is in light mode but i want to show you something very pleasant which is the normal telebugs dashboard and instead of saying there were 5 000 error reports it says zero because this is our median day that i know i i genuinely expected that we would have At the least a report that an extension had broken I really did expect someone to report that we had broken some kind of browser plugin. And so, if we look over the last seven days this chart is going to take a second because. You know when our median number of 500 per week is like one or two. I didn't want to allocate a big VPS, so this is like the bottom of the barrel $6 VPS on DigitalOcean, and so it struggles a little when there are many thousands of reports. So, yeah. Can you see on the chart where I deployed that PR? ocramz_yo somone give chamlis_ a raise
So all of these, I could click through and resolve all of these, but honestly, I'm just going to leave them to get garbage compacted. Televogs has an aging function that's both age and arrays. Yeah, that would be great. That's both age and size based. So they'll roll out of the database. There's no need to actually go resolve the... hundreds of different kinds of false errors. So anyways, that's in a real good state and it makes telebugs useful again, which is the real valuable part because there were so many false alarms, we couldn't see actual 500s. All right, so then what else? I threw in a refactor Yeah, everything is pretty quiet on the issue front. Did I resolve anything from the last stream? No. Fix the sorting. No. There was one issue. Well, there was this one, and I don't remember what the title was. I only remember the number. pushcx https://github.com/lobsters/lob…
This is just one of those So I filed this on screen the other day. What do you call it by coding spam? So it's mostly gone now. But. Actually, let me grab the. Let me give you a light mode warning because I'm grabbing. A PDF. So I got. spam on this issue all right here comes the light mode and i'm glad i saved i did a print to pdf because i tried to get archive.org to snapshot this page and it said it did twice but then it didn't actually take a snapshot oh weird the guy's username is this is some quirk of the print style sheet that these are missing usernames so this guy I've got it in another tab somewhere. ChaelCodes Yikes!!!
But yeah, this is just spam. This is spam of buy my coding tool. And very funny, like I'll personally iterate on the PR. It's especially given that this is conspicuously LLM slop text. The fact that he's like, oh, you have my assurance that I'll make sure this PR gets fixed. ChaelCodes But only 3 times.
I mean, it's just like the most worthless promise in the world from a spammer who is selling a tool to automate their thing. Like, I don't actually believe this person. You come in with zero credibility when you're spamming. Yeah, I know. Like, I won't actually fix anything, but I'll waste a lot of your time. And so I clicked report on this to GitHub, and they deleted his comment, and they seem to have... I noted it. So yeah, he left this long ass advertisement. And then the bot left a follow-up ad because he instructed it to post. And GitHub hasn't yet deleted this. So I guess I will. Yeah, well, let's block the spam bot. So this is spam. Okay. Okay. And H-Wayne is saying that escalated quickly because, so I can't even see the user comment here anymore, but if you clicked through to his profile, it is gone, gone right now. I would not expect that to be permanent. I wrote a little about it down here, but when GitHub is investigating things that are conspicuously spam, they tend to just completely vanish the account for a couple of days while they're investigating to figure out is this spam and the account should stay dead? Is there anything redeeming? Is this account takeover? Because if that person, I think it's very unlikely in this case, but they want to be thorough. If the spammer had been taken over, well, then they want to delete everything from the point of account takeover and reactivate the account. And if it's actually kind of frustrating that they do that, if the user has ever contributed to a repo in a good way. So I got to give this spammer a name and I don't remember his name and it was missing from that PDF. So let's call him Bob. So if Bob had opened an issue ocramz_yo all of their company blog posts are also signed by the bot :/ https://repobird.ai/blogs
five years ago on some other repo and then there was a long discussion about how to implement it and you know all of the considerations and doing a big refactoring while bob's account is in this disappeared state that issue is gone not even repo maintainers can see that issue And I sort of get it that when they impose that quarantine on an account, it takes everything because part of that is figuring out how far back. Oh, that's really cute. Yeah, I banned that domain and the guy's personal domain from lobsters after I checked that it was actually him, you know. And so he had an account that was years old. If he opened an issue or a PR somewhere and it was hanging around open with tons of other discussion on it, that vanished. And hopefully GitHub will restore it, but we'll see. So yeah, irritating to get spam from a vibe coding tool. It was especially irritating because Of the topic, which is, I am admitting that we have serious bugs in an absolutely key bit of Community design. graefchen Hello limesHi
Where, yes, this is a code bug, but the point of this is to enforce a social norm and try and keep the site healthy. and admitting that we had a bug in that is, you know, you have to be vulnerable to do that. It doesn't look good to say, oh, yes, this absolutely core control has been broken basically since the site was created. And so it is especially irritating to get an incredibly thoughtless piece of spam on that kind of thing. And I don't think he selected it. I don't know how he picked his spam targets. But I obviously thought didn't go into it.

18:56So the other thing. The other issue. But a little bit related. Is that I posted this, I saw a nice article on lobsters about maybe I saw this on HN, I don't remember about. improving our tests and I got this comment and boy does it smell like LLM output because It is a bulleted list of that just regurgitates what I wrote, so I wrote like a to do list of here's the things we have to do, and then they wrote this long comment that's like here's all the things you told me to do and there's no new information or what there is is a weird extrapolation like expired cookies. graefchen Also it is a Bullet List without Bullets. limesO
that's I wouldn't necessarily some expect someone to notice that our sites. cookies don't expire a human could have made this mistake but boy does this one smell like LLM and especially when I go look at their profile and their latest repo is a hello world with like the example of how to merge a pull request And then there's, you know, it's not like a minor typo here. easeout i definitely detect a pork product of some type
Not quite the native English fluency that this comment is written in. So, oh, yeah. And I guess people seem to think that em dashes are a sign that something was written by LLMs. And I use a lot of So I'm kind of hurt by that, but I did see one here. So anyways, I am trying to engage positively. And I reminded like, let me also note, we don't accept PRs from LLM coding tools because of their uncertain legal status. I would bet we never hear from this guy again. But so we were kicking around the spam in the chat room and technomancy who's a site regular and a chat room regular pointed out well you could avoid a lot of this by switching to another code forge like self-hosting what's that one for j-hole spelled like forge joe but we would lose the fact that it is hard enough to get contributors when basically everyone is already logged into GitHub and knows how it works and is familiar with the PR flow. If I have to say like, oh, also you have to sign up to this site or you have to find this site and sign up to it and learn how it works and learn what it does instead of pull requests, I think that's kind of the end of getting as many contributions as we do. And then also most of the protection there that we don't get LLM spam, just comes from the fact that it's a tiny instance with no popularity. And if, this is down here.

22:53ChaelCodes Yeah, are you going to lose chamlis in the move? Can't have that.
Yeah, just writing this down. One of the problems with, yeah, can't lose any of the contributors, like Thomas or who are, or actually ease out, who are all here in the chat room right now. Running a standalone forge, not only do I not want to host more moving parts in general, It's really only protected from spam by virtue of being a less valuable target, by not having any visibility, by being small and unfamiliar. I am sure GitHub has an enormous fully staffed anti-spam team and like developers who are dedicated to anti-spam and dealing with stuff like that spam we just saw, where A random forge that I install is just going to be protected by obscurity. And LLMs are the perfect tool for scaling spam. And so obscurity doesn't protect us then because someone can use maybe a vibe coding tool. either to make a bot that targets that specific kind of forge or just a general purpose tool that's find something that looks like a code forge, find something that looks like a login form, fill in the login form, deal with any exceptions you get, check your email box, click the link to activate, find something that looks like a comment text area, right? chamlis_ just as a datapoint, codeberg is at the scale where it's had to deal with spam https://blog.codeberg.org/we-st…
So where currently small forges are protected because you have to write in code Frici I can see the boon of using a small forge but also just because something sounds like a silver bullet, doesn't mean you should aim it at your foot.
chamlis_ the larger issue is definitely the network effect though
a scraper that says, let's look for an input type equals string and an input type equals password in the same form, an LLM does not have to have a brittle base like that. An LLM can, if you write the tool to hit the LLM, the spam tool to hit the LLM, during a spam run it can be incredibly flexible ah yeah so this is yeah so this is codeberg and this is no knock on them but they're 15 17 years younger than github So I remember when GitHub introduced, was it organizations? No, it was when they introduced the idea of being a dedicated maintainer. WhiskyFueled42 been hosting Gitea/Forgejo instances for a while now - leaving the registrations open is a nightmare. Spam bots are really common + other problems
One of the kinds of abuse that happened immediately within days was an attacker said, okay, so we'll have Carol, the regular user and Mallory, the bad user. And Mallory would create a repo named something offensive or embarrassing, like the I hate protected class, or just, you know, imagine a repo name for all the racial slurs you know. ocramz_yo ugh
And then they would add Carol as a maintainer, and Carol would automatically be added, and Carol would have her name and avatar appear right alongside it. And When you are doing social software design, it is a skill to look at every feature and realize how it can be abused. And GitHub did not have somebody working on that feature to recognize how it was inevitably going to be abused. They have certainly hired those people because now you have things like you will be invited to come maintain a repo or invited to join an organization, you don't automatically join an organization, which is you would automatically join maintainerships and organizations previously. And so Codeburg is going to, this sounds like they are very publicly learning that skill of, oh, we have to design everything with abuse in mind, unfortunately.

27:35Yeah. So I am not surprised that that kind of thing happened to Codebird recently. And just kind of having skimmed that post without any notice, it sounds like it was a real learning experience for them. And probably they will make more resistance stuff in the future. dlamz is lobsters leaving github?
But it's rough. And it means that there are a lot of things that you can't do because there is no way to prevent the kind of abuse. No, Lobsters has no plan to leave GitHub. We got some spam in the issues, and so we were kicking around. dlamz phew ๐Ÿ˜Œ
Someone had suggested it as an option, and I was trying to talk about the things I value, like GitHub actually has very good anti-spam protection, and GitHub has the value of the network effect that everybody is logged in already. So I just, where are we? pushcx https://news.ycombinator.com/it…
dlamz i have to use codeberg for some projects and the 500 errors are non stop
how do you find come here show me any user and then i just left a comment on this over here on the orange site about github and this is kind of a thing that i have kicked around a bunch in lobster's comments and then you know i'm just reiterating myself in another comment that The big, especially because GitHub has gotten so flaky. Oh, that's unfortunate. But so I was saying that the GitHub single page app has become very flaky. The big remaining feature of GitHub is the network effect of coworkers and potential contributors already being logged in. And Microsoft kind of infamously never breaks backwards compatibility. So I think if someone wanted to create a much different alternative to github i think there's a big window available and the big thing to have would be bi-directional sync because if you can bi-directionally sync issues and pull requests and of course the code but that one's easy with git but if you can sync issues and prs that means you can slowly migrate people away from github kind of like with jujitsu because it supports git underneath all of a sudden github is unofficially jujitsu hub and i think the biggest reasons that things like gidea and forge for jo i'm going to stumble on that one for a while obviously i've never talked about it aloud before only typing they haven't made bidirectional sync and so migrating is this i think we just yeah we just had this post where it's talking about doing a hard jump over of like you archive your github repo and you put up your codeberg repo and then you have a flag day where everyone has to switch and everyone has to move and that's Fine if you don't mind losing all of your contributors that are not paid employees. Because paid employees will jump through the hoop, but rounds to nobody else will.

31:13And that's the big reason that I have no plan to leave GitHub. If something showed up with bidirectional sync of issues and PRs, especially something like Gitbug, which syncs issues into the repo, that opens the door. That makes it possible to say, okay, let's seriously evaluate other options. Yeah, there's that. We just had a...

...54pushcx https://lobste.rs/s/slhe5j/how_…
There's an article or talk recently. Yeah. So there's this 2017 blog post about how Jane street does code reviews. And then they have updated this in the last eight years. They have a podcast. What is it? Jane street. ChaelCodes I'm curious to hear what you think about GitLab because it hasn't come up.
I think it's like signal and noise finding the signal and the noise. Yes. So. This podcast is kind of interesting. It is not shy that the point of this podcast is that you should come work at Jane Street as a developer. And so they kind of interview their employees to talk about how great it is to work at Jane Street. But they do some pretty interesting things. And so it's still worth listening to. Someone here in the last couple episodes was talking about code review, and I don't remember who. They were...

33:05I kept calling it a brain. Where's the date on this? Yeah, of course. pushcx https://www.janestreet.com/tech…
Who would put dates on a company blog? they do a thing with stacked prs and interdifs basically this is interesting because then one of the things that's especially attractive about it is all of the activity happens in the code repo itself rather than on some sidecar service that eventually you have vendor lock-in like we have vendor lock-in with github because we have so much history and discussion in pull request comments and there's no convenient way to export that and i know someone probably chanlis is immediately googling tools that export prs i don't mean to be the ones i have played with either they have the code but not the comments, or they have their own weird proprietary format, I am especially interested in something that extracts issues and pull requests into something in the repo in a way that a human can actually look at it. And then Chao, I don't mean to ignore your question, but I don't have an opinion about GitLab. I have used it barely for one project. It's been years. I just don't know anything to have an opinion.

34:58Oh, can't type this morning.

35:17chamlis_ that's not how you get viewers
ChaelCodes Okay! ๐Ÿ‘
graefchen So changing that the "only truth" is only the repository. limesHmm
ChaelCodes LUL
What else? easeout which would get you bidirectional sync straight away
Yeah, I mean, Graf Chen, you've kind of put your finger on it, that one of the things that these different services all have is they're all external to the repo and they all have their, I mean, I say vent, new silos, vendor lock-in. ChaelCodes But it's how you get _good_ viewers
And I think it is, you know, there's like 15 people watching, so nobody's going to jump on me right now about it. But if I had written in a comment that I want to avoid vendor lock-in, people would say, oh, use this open source solution. That's great, but that still locks up all of our issues and all of our PRs. It's just in a different system where I actually have the database schema. And that's nice. But unless the export script or the sync script already exists, that is a kind of vendor lock-in. It's just to a vendor that's not super strict about trying to lock the gate on their walled garden.

36:44So I've been... ocramz_yo love the MOTD
looking at issues and rambling for like 35 minutes my plan for this stream was to work on a mod q tool like we discussed on stream recently because i kind of was looking at different projects and that seems the best thing to pick up and improve so Rails DB recreate. Is there a recreate? Nope.

37:39ChaelCodes 41 minutes. :)
I'm going to get some fake data into the database. Did you create but not load the schema?

...59What are you thinking about, Rails? Man, you can tell I've been working with Rails for a while because I keep falling back to running these as rate commands. Do we have our schema loaded? Rails, fake data. There we go. All right, so we'll get some fake data locally. Let's stand up the server and sort out where we are. So I think the fake data now has enough detail in it that, yeah, because it makes flags and it makes votes, so the mod dashboards that exist shouldn't be totally empty. Let's, oh no, that's my new code. Well, let's fix that bug.

39:22graefchen I would describe it as "Vendor Independent", where the "only vendor" you need is Git itself. limesHmm But it sound indeed very hard to do. limesD
ocramz_yo re. code forges: there are also alternatives based on ATProto, like Tangled: https://blog.tangled.sh/intro which seems to promise data portability
So a thing I worked out on the last stream. Yeah, Tangled is interesting. I actually thought Tangled was going to have a different focus where they were mostly worried about the data layer of sharing repos and syncing things. And they've actually been putting a ton of energy into building a whole new web front end. So Yeah. Oh, crims. What's the, Oh, the, The new shell message? Yeah, I have the D-Day utility in there. I have forever. Forever, I mean, I don't know, 25 years, as long as I've had a Linux machine of my own.

40:19Man, look at the draw that I hit that bug. So let's find where it makes flags.

...36We're going to have to do both directions, actually, of. So it was in comment flags and votes. Right, so before here. Yes, I think it does all of the replies and then it flags stuff. So this there's a kind of a performance strategy happening in fake data where it writes all the data to the database, but it also keeps it in memory so that it doesn't take on the read trip of going and selecting the data that it just wrote out of the database. But it's not quite in the format we want. Because here we don't record who is posting the flags.

41:52ocramz_yo you don't color your syntax? CoolStoryBob
I guess we could just rescue that validation error and throw it away. That seems like a bad plan because we'd have to get pretty detailed. Oh, cramps, no. There's a stream FAQ where I don't use much syntax highlighting, but if you look at the comments, they have a different color and the literals, which... There really aren't any on stream. I guess this string here on 102 uses my italic cursive font. Knowing that something is a class or a method or a expression is not, or like is a parentheses, that is not useful information being conveyed by color.

43:12Yeah, so the way we're storing this, we don't actually know that the user has left a reply back up in this step unless we start tracking that, which. It really is luck of the draw that that run happened to hit this bug. Because it had to have the user Create a reply and then had to reselect that user for leaving a flag.

44:13so we'll just track this and we will say that replies with x user no we have to go the other neither of these things is a natural key because We might see the same comment multiple times and we might see the user multiple times so really our key is the user and. The parent comment let's just make these both ids because I don't like the idea of having one be an object and one being an ID.

45:06When we're flagging here, we will say, next if applies, has a key, UID and CID.

...40Sounds like the cheapest way to do that. You've already got data. Do you want to add more? Oh, didn't notice. I thought it was supposed to. Of course, having done half a run before, the chance that I hit the bug on this run is significantly lower.

46:15But I feel pretty confident in that code.

...26All right. So if we got this. Oh, there was also on stream. It's in that funny situation of waiting for a slow test where I want to change topics. But then I'm not so 100% confident the slow test is going to pass that I want to unload the code from my head. I want to.

47:14ocramz_yo is it running through the whole lobsters DB?
Why did it print dev no? No, so we have this task called fake data. It's, I'll share a link. That's not what I wanted to link to. pushcx https://github.com/lobsters/lob…
So it's here in lib tasks. It's a tool for developers. And it tries to create reasonably well-structured fake data in the database of a bunch of users, a bunch of comments, and they're all lorem ipsum. But now looking at my development copy, and you can tell it's development because it says local host instead of lobsters. God, I would cry if it said lobsters because that would mean I'd ran that on prod. And I'd be like, OK, stream is over. Time to restore from backup. Yeah, but it creates some data with a reasonable amount of verisimilitude where it's like, yeah, okay, you do often see short comments and then long comments and replies and maybe a chain of replies and these have different scores on them and some of them, oh yeah, they'll even have like the moderator deleted this comment. So it is nice for, webburnout why is the fake data task so slow?
debugging because you have a site that's not dead empty. So let's make a new commit. The fake data task is slow because it's never really been performance tuned and we wanted to keep it simple. If you are a Rails developer and you see performance wins laying around, you can go for it. A big one would be, no, we already have it, to turn off transactions. But at the same time, it did make a couple thousand records. easeout having hand edited prod in the past, the real price you pay is the flashbacks :D
So we got 53 users, that many comments, and then 12,000 votes.

49:40flashbacks yeah yeah there are some interesting tools for that i've seen things where like you can't log into prod you have to write your data repair script against staging and then someone else has to sign off on your data repair script for it to run in prod. ocramz_yo does fake_data also test time-based behavior like post frequency?
And hopefully that adds both a code review chance to catch a bug, but then also an audit log of what you actually did so that when you see weird data in the future, you'll know. All right. So I was going to say there was a mod controller that did not live in the mod namespace, maybe it's time to move this in. Especially because it doesn't inherit from the right thing. Fake data doesn't test anything, no. And I don't think it tries to create synthetic dates on the comments so that they're spaced over time it's not quite that sophisticated it's i i've touched it up a couple of times but what's basically happening with it is we are trying to have it we we add more detail and more verisimilitude as needed so when someone for a long time it didn't ever flag comments or it didn't delete comments and then we were debugging something related to flagging and deleting and did the user delete it or the moderator delete it so then it made a lot of sense to add that to the fake data and until then yeah which I could throw that in actually as a comment fake data let's edit let's jump back a commit

52:43what am i trying to say i guess what i want to say is if you are working we mostly improve its do people know the word verisimilitude i guess so

53:44I'm trying to both explain why it looks like this and that people should feel autonomy in making improvements. And I can't say both at once.

54:44That's what I want to say. Okay. let's make a new one for, I don't know, odd controller, super class fix, because this should be, yeah, this should be inheriting from, mod moderator controller and should probably move into the mod folder at this point so let's go ahead and do that yeah

56:11These things this is we'll call this the dashboard controller this is kind of. let's call it the flagged controller because all of its actions are. You know, before I do that, this is one of my my rails isms that I wish was a little easier what I want to do is run rails routes to before. And then move the controller. And we'll call that the flagged controller. And then this becomes

57:17These all want to move in here. And I think I just. Yeah, I think I can just drop this.

...43Then this becomes.

...51I don't often work with the modules in Rails controllers, so you're seeing me not remember the syntax for these. As mod flag stories counters. So then after, if, before, after. So what did I break? This is good. This one's got to change. And it's just this one. That one stays the same. I think mod notes is not in the directory and should probably go in as well. We'll check on that.

59:06Do I have a way with this diff?

...32that's not what i want 50 nope that's that's not helpful all right i'll stop playing around with tooling i just wanted a an inline diff that showed me the individual words that were changing because that would make things like your the the functional change here is to change to insert the word flagged at the start of this as it is i have to look up and down yeah so this became mod mod flag that's not what i want let's put that back

01:00:44OK, so this looks good. These URLs, that one broke because I left that on.

01:01:01And then these things, their names stayed the same. And they just changed what controller they're under. OK, that feels just about right. I also wanted to move the notes under. It's kind of funny. The mod functionality changes so slowly that we often end up with things where it's like a year behind on Updating. All right, so let's move, come here, move app controllers mod notes into app controllers mod. Let's go find that notes controller. And OK, does it does at least have the right inherit? It doesn't need this before action anymore. I guess this becomes mod colon colon notes controller. Which means this goes away. That goes away and could probably be a resource. Yeah. Oh, it's the period, though, I don't think you can handle that. Let's let's do less shotgun surgery. So this. Is the change I wanted, yes. Let's see if the tests run. So just off the top of my head, how long ago? Yeah, so that was only six months ago I did that. Maybe I did that back in December.

01:03:24yeah all right so i started that back in december so long time on that refactor all right so i didn't call it flagged or i didn't have the namespace on there so we caught a bug yeah you know i said everybody i said i'm gonna work on mod tools Which sounds like super interesting and you know kind of dramatic this is how we ban people and a lot of it is just this kind of getting your rails routes shorted out sorted out and. Making sure the tests are still green and etc.

01:04:11Thinking about that one spec there huh. Why is this one spec stalled. We should not have any specs that take a full second, let alone many seconds.

...31I'm both curious to leave it running to see if it finishes, and I want to interrupt to know which one it is. If I cancel, am I going to have... I'll probably have the test and the trace back.

...54Yeah, our spec is .. No, we lost it.

01:05:02So let's say dash b and dash v and see what that gets us. I thought it had a robust mode where it printed the names of the tests as it ran.

...37That's what I want. Oh, well, that's conspicuous that it's getting wedged here in a thing I just touched. So what does that log in mod only rouse?

01:06:12this spec thing you know what i really would like out of a ruby testing tool is mini test with a proper runner or rspec with like 10 of the features because the rspec runner is pretty nice but its whole idea around Like let me print you strings and let me print you this instead of a file name. It gets me. So it's probably this one because it's describe login. You don't have the text mod only. Oh, the authenticatable also uses the word login.

01:07:18And since it's so string based, it didn't notice that there was a collision. And in any case, the word login does not automatically lead me to a spec. And since it's possible to have multiple kinds of specs of this could be a request spec, a controller spec, a feature spec, a model spec, having the word authenticatable does not actually help a hell of a lot. So Why is it failing? I don't actually know.

01:08:03This kind of stall is something I don't often see out of Rails, so I don't have something in my toolbox to debug. So let's u equals user last. What's your username? Oh, that's awful. I'm not typing that. Username. equals Alice. I've already done Alice, Bob, Carol, let's go Dave. U password equals test save. Oh wait. U modder is moderator equals true. Great. So as long as that spec is just hanging out frozen. Let's go poke in and see what happens for me. As fast as I type Dallas. All right. Yeah, so this is one of those ways that the fake data task is not realistic. Well, I guess it picked them randomly. Huh. Funny how biased that is to the last couple of stories. weird all right so let's go try to load whatever page this stalled on which is slash mod that's a big autocomplete that i didn't want firefox no view template for interactive requests Oh, so I didn't move the views. So let's do that.

01:10:00yeah so views move mod notes into mod slash notes and then yeah those things they look like they're in the right place So if flagged controller should have, oh no, they should make a new directory now. And then flagged everybody and index into flagged. That's fine. That's better. Sub nav too. Okay.

01:11:01So that is probably also the cause of the spec failure. I should have put the format on. All right, so it passed. All right, so that's... Let's run the whole suite, but we're probably good to move on from that. Renaming, refactoring. And while that runs, let's just click around a bit. So this is what the mod dashboard looks like. I'm surprised nobody shows up there. I guess nobody got two failures. So this initialize constant mod notes controller okay oh we gotta change the file name and then check on that notes what did I call it if not mod controller oh did I call it moderator yeah I don't love that so one of the Conventions has been internal stuff for the mods is called MOD and the external stuff has the full word, but it looks like I was inconsistent and naming this so let's let's go look at APP controllers MOD star.

01:13:15See it wants to be moderator controller.

...27Yeah. Did I not save?

...40You're going to complain it doesn't exist.

...55Did I leave the old copy of the notes controller in place?

01:14:07Yes.

...18And I guess I made the rename in the other one.

...32Better. Period is over in, where did I define that?

...46The traffic helper, why is that not mixed in?

01:15:03So that mix is from Application Controller, which I have open in some other window, apparently.

...47Puzzled by that one.

...57I'm real puzzled now that I've mixed it in. It's probably not going to, yeah. all right so what's the bug the notes helper notes controller is inheriting from the moderator controller moderator controller is including the traffic helper traffic helper is defining the method right what is now who's defining the method

01:16:42lag why is the notes controller trying to run a function that's over there so we inherited from mod controller oh so that was an interesting error because i named these things so generically it was inheriting from that flagged controller so this isn't traffic helper which is odd because yeah so let's do that and then flagged controller has this stuff. Let's grab this period function. Yeah, all this can be shared between the mod controllers.

01:18:38Right now notes is not there, so it needs to refer to the modern sub now.

01:19:05Okay.

...17The subnav should be shared, and I shoved it into flagged. Yeah.

...29One thing I like about Jujutsu over Git is because it's always looking at things, even when I get to the commit stuff, I never have to tell it about renames, deletions. You can delete before and after I'm done with those.

...51and then also the wagged so view mod wagged These guys have to change. It's easier to do it this way. And views mod. Yep. This is the Nerdtree plugin. Let's see how our tests are. Let's see how our browser is. Oh, browser's still mad. Did I not rename the file?

01:20:39It is there. Do you care about that?

01:21:10No.

...17So it's certainly there, up one directory from flagged. There is subnav. From notes index, you can't find dot dot subnav. But it's there. graefchen One path down to much. :limesD:
What am I missing here?

...47graefchen * limesD
i don't think so because i only went down one level from notes so it should have looked in mod right so app views mod subnav right that's one directory up from flagged and up from notes

01:22:14graefchen But not the one in notes.
So app views, mod, notes, index. I'm missing something very obvious here, but not the one in notes. graefchen Or am I stupid.
So Grave, the delay is making this harder. Can you be explicit about what is one path too much from what? Because I can't follow your partial it. Can you say it without any pronouns? Not to sound like I'm on rumble.com, but be explicit about all your nouns.

01:23:23graefchen As I understand the error is in notes/index. And you try to go one directory down to find _subnav. limesLurk
Everyone is mad about it now. But it's right there. The errors in notes index, and you try and go one directory down. No, I'm trying to go one directory up from flagged to its parent directory. So dot dot slash takes me to the parent directory. So from app views mod notes index, one directory up would be app view mod.

...53But here, oh, wait, is it? So it search and app views. So for some reason, it thought of itself as being in the mod directory, not in mod notes. So if I just change this to subnav, would it work? graefchen Okay. The I am dumb. limesDizzy
Missing partial mod notes subnav, moderator subnav. Okay. If I said mod sub nav, it's doing something very clever about what it considers the route for these views. And I don't know what it's doing that's clever, but it's so clever it doesn't actually work. So I'll Like that is not where I expected. It was going to be relative to. All right, so that's fine. That's fine. let's see if the tests want to run now and you're not dumb it's just rails being unobvious all right we've got one set of failures in user administration Maybe that link has to change for banning. View user show. That goes to user unban path. Does it become like mod user unban now? Rails, Rails, Ramp.

01:26:16It's just on the user controller. What's the test failure? Unable to find link or button. That sounds like you're not logged in as a moderator. Although actually all of these are administration things. Why is administration broken in this spec?

...49Create a user named admin.

...59Is stub login as not working?

01:27:14You know, I bet it's something about logging in as an admin. which we haven't run in the browser here. So let's say u equals user.first, u.username equals, so Dave is the moderator, Emily will be our administrator,

...51Let's log out of Dave. No, Emily logged in fine. All right. And let's go find a user. Oh, but the UI for the administrator is missing. So here we should see, as Emily, we should see the buttons too. That's a very strange disappearance.

01:28:32So let's see. Yeah, so we ask if that user is admin.

...46So now we got Emily. Is she the admin? True. Where's my form there?

01:29:07was this i don't know what this is yeah so emily was set as the admin but not a moderator and so she didn't get into this section and then the test was not catching that it was getting 500 because it wasn't even looking at response codes okay so this becomes mod slash notes there we go there's all my nice admin ui and i bet those specs pass

01:30:07What was it?

...19chamlis_ hurrah for tests
Yep. All right. So in case you're curious, these are things moderators and admins see. Yep. Even if they didn't directly catch the failure, they pointed to it. so moderators can see this little color cutout also you can see this on your own profile if you're logged into the site and users look at this because it is very conspicuous when someone has just signed up or reactivated after a year or two of inactivity and in the last six months you know, they have posted zero comments or they have posted three comments, but none are on stories they haven't authored and none, or, you know, maybe they've posted a few and they're on other people's stories, but they don't reach an above average score. And that, you know, then I'll go look at the comments. And if all the comments are like, this is great, thanks for sharing. It's like, okay, you're just leaving BS comments to fake participation. You're not actually participating in the Community you're just treating us as a traffic source, and so this is one of those MOD actions that does not appear in the MOD log because couple of times a week we send someone a note about self promo. And there are. it's not yet a strict ladder of responses of. someone is brand new if they have no activity if they have activity but it's kind of bs activity if this is their first time and it's very commercial if this is their blog is very well received and topical but they're not participating at all so we kind of have a loose flow chart for these things for how stern the message is that the user gets. It is not yet a strict flow chart, mostly because, well, I've been trying to talk one of the other moderators into writing a strict flow chart and a set of stock templates, but they're busy. So then below this, yeah, there's the moderator info that you see. Someone's profile also shows the last couple of notes. If you've watched one of the recent streams, I also showed off all of the tattle notes. You can see the last activity for other moderators interacting. This is very valuable of, you know, if I see that a moderator has had to be like, hey, no insulting people or Hey, this is Family Comic Comment. So this helps us build context and always reply with the context of what someone has done. And then just for the admin, you can also see recent votes and this is really nice for finding voting rings. So if, what letter are we up to? If Frank, Genevieve, and hilda all look like their co-workers as a company and i look at their three profiles and they are only voting positively and only voting on each other's stuff well that kind of stands out as voting right or if what am i on i if ian All of his recent activity is to flag one particular user across 10 different stories. Okay, and you are using the flag system to produce a grudge you're going to get a grumpy note from me that says hey don't do that. So that's why this is there, and then of course there's the interface for banning and disabling invites and it looks like this test user already had their invites disabled. disabled comments doffed yeah so very similitude so we finished we finished that commit let's make a new one you know we really did move all mod controllers into mod with super class. And it really is just like one liner to include the moderator off. And that's the only thing in mod controller. So it's not a big deal that we're so belated on doing that. But especially for stuff that's not super urgent, like most mods stuff that's been in a stable place for a long while, I don't tend to I don't always finish refactors, frankly, until they're needed. So this is weird. I guess fake data doesn't make any notes. Why don't I see any flagged comments? I guess the fake data script must not be flagging a comment multiple times. So if there are no flagged comments, we see this happy little lobster. And that's always pretty great, actually.

01:36:16Looks like I missed something. So flagged controller commenters.

...39Should be an app use mod flagged. that's better now we're just getting that sub nav complete because that's the one file i didn't touch this one also wants to be mod like now we're two levels down all right also wants to be good nice to click around and catch that stuff so let's go find my notes on a mod work queue because that was a big mod There's my m dash. I must be an LLM.

01:37:35As long as I'm breaking all that stuff, do I want to fix that one thing that was named moderator controller instead of mod controller? I kind of do.

...59Yeah.

01:38:22graefchen em-dash lilith3Panic llm detected limesGiggle
This convention is a little bit confused by the fact that Grave, you may be way behind on the stream because I think I said that like 60 seconds ago about MDash. Reloading Twitch usually catches you back up.

01:39:00This becomes on control notes. It's my controller parent. Yeah. Stories controller. All right, let's see if everybody still runs. And I can still load pages. That's good. Over to the other controller. Yeah, this dashboard, there's really not much to the dashboard. It tries to combine notes. graefchen Nah. I got an 5 sec delay. I am just to slow in choosing the right emotes and trying to be funny limesO
This little red indicator was trying to show to highlight activity by mods who are not you. But because the user activity is mixed in here, it doesn't help out. Ah. Okay, you're good then. Alright, so there's that.

01:40:43It is a little muddled by the fact that users always say mods and mod log, but that's okay. I would rather have that little bit of reversal than change a whole ton of stuff. Also, it's under mod where the public mod log is under slash moderations. All right. lot of code cleanup. I didn't remember there was so much.

01:41:38So the work queue, this is actually pretty similar to the notifications model. And I think that Thomas recently implemented and worked through. And, oh, Thomas, if you're still listening, zero bug reports and zero complaints about the new notifications inbox since rolling that out. I thought I would at least get a comment on, oh, this UI is a little bit different I think part of not getting that is that DMs are pretty uncommon on the site. Most people don't get any in any given day. So maybe folks aren't noticing that it's combined. I get a bunch. I tend to get two or three notes a day. So pretty handy for me. not notes because i'm looking at the notes here i should say dms that's the other part of a work queue is i would like to have a a mod mail system where all mods can interact so pushcx This is Lobsters office hours, ask questions about the site anytime!
i've been going for over an hour and a half so let's go ahead and do the the bumper that this is this is lobsters office hours and it's questions about about the site anytime so if you've just tuned in you can throw a question in here whenever you like and is someone talking to me on irc Yes, but it's actually from last night. And I already handled it. Cool.

01:43:44So what do I want to do? I want to make a model.

...56Yeah, I wish Rails had better support for some types, because there's a bunch of places that we treat moderation objects and note objects separate. And I really would like to have them in line together. So we looked at that profile a minute ago. Is that still here? Yeah, so we have two tables. One is the latest mod log for this user, and one is the last notes. it irks me to no end. And I would like to have the two of them combined. Because the point is, I would like a list of most recent events. And I don't want to have to manually interleave them to be like, oh, we gave them this hat. And then there's a note that we heard that they weren't actually involved in that project. And then they came and doffed that even before we got a chance to do it. And then we left a note saying, well, Maybe it wasn't fraud, so we don't have to ban them right now. I'm making this up. But you have to scroll up and down, and that's super irksome. But SQL doesn't love some types either at the column level or at the table level.

01:45:23But, you know, now I have Thomas's pattern for notification. Let's go look at that for a second while I daydream about.

...41Yeah, if I could name. A superclass, not a superclass, but like a mod notification.

...56Then I could just steal this pattern. And I could call it like mod activity. That's not a bad idea.

01:47:12So one other place that this same thing shows up, and actually I think we kind of punted on it, is if we go look at one of these, there is a, yeah, so somebody submitted this. Moderators also see a list of users who are hiding the story. but then also see a table of, hey, this is what's happened in the last month or two with this user. So it's every moderation that is related to the story or related to the submitter. So if we've had to delete their comments or have sent them notes or something, well, obviously this doesn't include notes, or any activity in this thread and so this is a real quick way for us to get up to speed and be like oh right i remember detra detro was the one who left this awful comment where they called somebody a jerk face i don't know i'm so bad at coming up with these example scenarios because i want them to be I don't want anybody to think that I am, like, subtweeting things that have recently happened, because I would rather just talk about those directly rather than make drama or make a puzzle of can you recognize, ooh, I am subtweeting. That's just not helpful. This stuff is in the mod log. I would rather talk about it directly, but I don't want the distraction of talking about real examples directly when I'm trying to use example data. Anyways.

01:49:07That's tempting. graefchen Kindergarten-insults are always funny, and most of the times not so bad. I love "Silly Pants" as an insult, for some reason. limesGiggle
Which of my two fun mod ideas should I actually work on? We could do mod activity, or I could do the work queue. Silly pants? That's a pretty good playground insult, actually. Are you British? So Americans say underwear. or name the specific kind of undergarment. And the British say pants.

...59Right.

01:50:15I think I want the mod activity first. Because I would just be copying that pattern, and it would solve a longstanding hassle. graefchen No. But I heard it from an Older Podcast from 4 Brits. But I technically learned British English AND American English in School here in Germany. limesLurk
easeout go for it
And I'm very sure I can power through that in my hour five before I go and throw two chails. I heard it from an older podcast from Four Brits. Ah.

01:51:03Do I want the prefix mod? Yes, because this is just to combine mod notes. And mod notes, yeah. I mean, you saw me finishing that refactor of making the module for controllers just for mods. This will be, I think, the second mod-specific model, which is still a little early for me to want a module in the models namespace. But I would rather include this here because I want to kind of echo the mod on the front of mod notes because that one, I named it that way because I didn't want to accidentally start publishing mod notes because most mod notes are like, I had this DM conversation rather than automated things. And I want to not accidentally publish those. So we have the mod activity, what is it going to have well let's go look at. or notifications because i'm really just going to go this. shouldn't have a user ID. Because it's not being notified to an individual user. It really wants to yeah, this is the hassle with the some type, we may immediately bog down in rails modeling it really wants to join through the notifiable type the activity type to say, is this a note with this user ID on it. Is this a new moderation with this user ID on it. hmm. but i don't think yeah but this also joins and finds any stories they submitted any comments they submitted and the mod moderation object yeah that the user id doesn't get filled in This is just one more example of some types are a pain in the butt in SQL. Let's leave it off and see how far we get.

01:53:53Will you show me the column types? No.

01:54:11Because what I want is the, so that calls it notifiable. What do I want to call this? Activatable? That's terrible. Let's call it an item, I guess.

...38And then what else do we have? We don't have a Red Hat. We do want to have a token. I think it will include timestamps by default.

01:55:03Well, it's going to make me the migration, so what else do we have? Really, that's it. This is just kind of a join table.

...21What are we mad about?

...27Wrong constant name item references polymorphic. I was copying that from the help text above right here.

01:56:00oh that's what it is i didn't say mod activity lost it and then edit all right yep good this should be where's my note i migrate for a notification because i want to just

...41I got called reply notifications.

01:57:43Okay.

01:58:27So we create the table, and then we're going to go and create all the data for it, right? Well, yeah.

...54This is gonna be a slow migration, but we're only writing it once, right? Let's make a model method for this.

01:59:57Right. that's really it right well what we want to say is we'll do that and we'll say graded at is the let's say there's so little code here

02:00:33yeah there's a little code here there's nothing so let's just say on an activity create well yeah so what i want is some behavior around handling the timestamps on it.

02:01:30Then this has to have the token.

...47This can say, let's say create board. I do like that name a little more.

02:02:06As much as I gripe about rails writing this kind of high level declarative stuff is satisfying.

...32Even going to need that scope.

...43I guess this should be create bang, because I don't want to have to error handle here. And every place I'm going to be doing it in the controllers, I want it to happen automatically.

02:03:12Let's validate that.

...29I think that's it.

...39Keys are present. Yes, I meant to call validates instead of validate single. Mod activities already exists, right? Because on MariaDB, this doesn't run in a table mod activities.

02:04:06We have a unique validator. But there was a uniqueness. Right, because it transforms them into a adjective.

...44the morphic associations do not support computing the class the held is computing the classmate on activity line nine so you're mad about Something about setting the item? What? I don't even know what Rails is mad about.

02:05:38You were using validation.

...46Okay, so it's something about my validation. Wonder if it's the unique or the presence.

02:06:23Looks like it used to have a slightly different error message. A slightly broken English. Oh, no answer. Huh.

02:07:08Thomas, if you happen to be listening, did you see this one or. Notifications. It's going to be something about the validation. And rather than shotgun it, I'm just going to see if. Yeah, it is that backfill. Does basically this, right? Time, create a notification, set the user, set the notifiable, which in our case is item. That looks fine. So this doesn't have any validations, which is fine, but what is standard? Remove explicit presence validation for item. Okay, don't explain yourself or anything.

02:08:27That is such a not helpful error message. And I'm going to get the error that the table insists.

02:09:02All right, so do we have activities? Great. What if instead of, so let's go look at the schema.

...25Really what I wanna validate the uniqueness of is these pair of columns And I'm not sure that Rails allows me to express that.

...51You could do it with an index.

02:10:01But then at the model level, OK. So then let's try both.

...16So what we want to say is validates.

...26item well i guess item or item id say item id and the scope of item type all right and then library activity everybody else is suggesting and had index, which we already got. All right, so let's see if that works.

02:11:40good this is one of those rails conjugations that type equals taken no it's it's uniqueness just call it unique i understand that you are saying it from the other perspective but i would rather see the same word unique unique unique as opposed to unique uniqueness taken Keeping track of those conjugations is not my favorite thing.

02:12:17All right. So I don't think I need to recreate that or rerun this migration. No. How are we doing?

...38And then we've got to have the creation. And I want to say, so that's for comments, notification, no.

02:13:09how are these notifications getting oh it's not he did it with the rather than call the class he called notifications to create right touch

...57Ah, it's all in the notify message job, isn't it?

02:14:06No, no, that's deliver. Ah, this is the line I was looking for. That's fine that it happens in the background because we moved a bunch of... code i'm trying to get more and more things into background jobs that shouldn't happen in line like sending emails and hitting third-party apis so

...52This is where the Rails lack of a service layer pattern is a little annoying, because what I want to say is every time a moderation is created, or every time a mod node is created, but they can get created from anywhere. And there's I am definitely not going to. And more active record lifestyle callbacks, especially that create.

02:15:41That's well, that's actually a bug. Where's that commit? Let's jump over there. That's something I forgot to update here in, where does that live, that cop? Extras.

02:16:10Yes. Custom cops. Live custom cops inherits.

...35I may actually have to balance Vim to see that one.

...47Or no, this is just out of date?

...57How is this not erroring right now?

02:17:09backed up too far, that's how.

...23So type back in this command. Let's go edit the other one.

...44Alright, now everybody's happy.

...59Good. Where was I working? RZP.

02:18:11So here, after creating the mod note, we will create the mod activity because this is the only thing that makes mod notes, I believe.

...28Guess not. User's controller can create them.

02:19:14And what else created them? User controller.

...32Oh, that's just creating a blank one for the form. OK. Oh, every every single tattle does it. So this is where I want to start reaching for a lifecycle callback, but what's really missing here is a good pattern in Rails for this sort of thing. I either have to shotgun it into all the tattles.

02:20:18Yeah, I guess that's it. You know, we'll make a lifecycle callback and then I'll be mad at myself in a year or two. It's the rails way.

02:21:05Let me just give it a proc.

...28I'm not sure self will exist in that context. Let's find out.

...46Mod note doesn't have an updated at? Oh, right, because you can't actually edit a mod note. So I must have left that timestamp off. Yep. So then this wants to be item.

02:22:20I can't do the null propagation operator, but that is the basic thing I want to do here.

02:23:02helps if I actually use my new variable.

...15Why are you trying to create? Seriously, what is the backtrace on this? User's controller is trying to create the inactive user.

...52-huh. ah so it's a display thing so inactive user oh it's such a bad name so it's for the comment disowning feature i should have called it disowned comments and the inactive user is kind of confusing to see on a comment but i don't quite want to take on the pain of renaming it But then it's very generic name has caused it to get freighted in for other system use.

02:25:05It gets graded for tests. That's the part that puzzles me. I'm not seeing how it gets graded for tests because the tests don't throw this exception.

...46you you

02:26:20So if that creates me a fake user, I should be fine.

...28It's doing that off. You know, it's weird because I thought transactions were disabled, but clearly it's happening in a transaction because I can't load that page yet. Hmm.

02:27:14Join us now and share the software. I don't know why that terrible song... And you know, it scans for Girl from Ipanema. Obviously the only thing that could make a song by the Free Software Foundation better is setting it to one of the most irritating songs in the world. I wonder if you can sing that song to the tune of Baby Shark. It's the right level of... Yeah, let's not be catty.

...53All right. Why do you still think there's no user? Oh, because this hasn't finished.

02:28:14Why hasn't this finished? There we go. You thought about that for a while. Oh, and you still failed.

...36You failed? Oh, I bet there's some other field needed on user. like email address and password let's go figure out what the minimum thing is to do that in the console

02:29:13That's what it takes. So let's give you, you know.

...26Cynthia.

02:30:01what are we mad about it doesn't want to change those quotes because it can see i did interpolation i'm so used to letting standard rb change those all right so if i run this in a rails console good i mean that hit roll back because

...33yeah that's fine because i had already created the inactive user in the previous console session that should fix that and i can load this page good all right so let's go back to what the heck i was doing which was on mod note i added that after create ah yes so then i submitted so we created a test note one let's go see if we got a mod activity for that that points to a mod note id three good yeah good let's do it again just because that was such a long set of

02:31:42and then with that i can go over to models moderation let's go include token validations after create yeah so like this one this is the kind of business logic i dislike having on on models in hooks this one i guess i'm okay with it because it feels like internal plumbing so let's go find a comment from this user and delete it create an entry so that's number three If we reload, well, obviously we have nothing because we haven't updated the table. So let's go to. Use your show. And last and. Mod interactions. Who is that a better name than activity? Oh, it is. Oh, what a slog to rename it. That's fine. We're just going to do that. I'm not going to beat myself up about it.

02:33:55I query that direction so what I want to say is follow the item and I don't often use the rails polymorphic join so let's see how expressive that can be activity where go through the item and find that it has the user id of 60. So this is the user on the left. I can see it up here. Oh, but it's not 60. It's 66. What was I joking about getting my eyesight checked? Unknown column item dot user ID. Yeah, because you've got to go through the joins items. Cannot eagerly load the polymorphic association. Yeah, I don't actually need you to. I mean, I do need you to eagerly load it.

02:35:00Don't want to copy the user ID up.

...41Thank you.

02:36:11And this is one of those places where rails doesn't really support projections, because what I want is a projection of These two tables, but instead I have to do this polymorphic thing.

...40Do you have something about querying? That's often the other. Guide.

...58Yeah, there's no mention of this limitation.

02:37:26Oh that's hideous. That is the thing I don't want to do.

02:38:04That's a lot of detail.

...25This implies I should be able to do it. But this is just finding the one kind, and I want to find both kinds.

...42Commentable type is forum topic. Right. But then it's forum topic, the commentable type that I want to filter on.

02:39:03let's see

...49I think this is just saying that the I think it's just the puzzle of coming from comment instead of forum topic.

02:40:31Nobody is talking about see what I want is the union and rails doesn't want to support a union. This is not actually helpful.

...54And the reason I don't want to copy up the user is because I want these also to be used on the single story page where what i'm concerned about is the story and i want to grab different kinds of mod notes based on the moderation

02:41:42And what was all that about inner joins? Because I want an outer join so that it can be nil.

...59Because nobody is going to be joined to both. So all right.

02:42:08see if you specify table names then the eager loading gets real sad fast equals mod activities dot item id where see what I want is this where to apply right yeah on moderation outer join moderations I need a comma outer join mod notes where let's close that out because this is going to get long either moderations no let's do the type first where item type equals moderation and item id equals moderations.id or item type equals mod note and this is real ugly give me that to sequel select mod notes for moderations outer join moderate those outer join mod notes where see that all looks good what was this exception statement invalid near outer join moderations maybe because it looks like a valid query to me maybe it's missing a comma or something

02:44:42I can say left outer join not unique table slash alias mod notes well there's a typo that slipped in is that it

02:45:14So that is the table name. Not unique table slash alias.

...34Just didn't like that comma.

02:46:04All right, so we have some kind of fiddly SQL error here about these left outer joins.

...33That's not actually the problem here.

...43This left join RP. There's not actually a left outer join happening here.

02:47:06It just wants to call that left join.

...35yeah everybody's using the on all right left join on i'm in the wrong place left join moderations on item id equals moderation stop id left join Mod notes. See, this is going to be... And then I have to edit the where back to enforce the type.

02:48:25Yeah, not sure. I'm going to couple those.

...56This moderations.id is not null.

02:49:14Let's back to this. Oh, wait. This is starting from the wrong place. All of this that I was querying wrong, I wrote mod note instead of mod activity. Yeah, OK. select mod pivot t's dot star from mod So now I have 401 rows, and none of them are mod notes. And 99 of them are missing. 105? Yeah, OK. So this is partially correct. So if I specify that this is a left outer join, still don't have a mod note.

02:51:04drainiard hello! what are we working on?
yeah so we should have a couple of them here at the end and we don't hey drainerd welcome we are working on some moderation tooling for this website lobsters it is a open source rails codebase and community about programming pushcx https://lobste.rs/ https://github.com/lobsters/lob…
drainiard yep I'm a lobsters lurker :)
So if you go to the lobsters repo, which is over here, you can follow anything along. Oh, you're a lurker, great, welcome. So I am working on improving some display of moderation info, and the Rails ORM is fighting me, because I'm trying to basically get a union of two tables, and Rails does not know what a union is. And I'm trying it with a polymorphic join. Oh, you know what? It's the mod note versus mod note. I'm getting a case insensitive comparison by default. So that's why the first one worked and this didn't. No? I expected that to work. I also expected this filter to work.

02:52:37I said selecting all of these mod notes on item ID equals mod notes ID, where item type is mod note. Is that wrong?

02:53:08Can I get this to just give me the mod notes?

...22It won't join mod notes at all. OK.

...40So we are trying to select mod note three and four. And they do exist because I got rows back. So when the item type is mod note, the mod note's ID is not null.

02:54:10it looks correct all right so let's lift outer join mod notes okay

02:55:00But we saw those. There's some irritating typo happening here, and I don't know what it is.

...37Oh, it's the item ID filter. It's not the, all right, so let's put that, where's the big join? Should be the mod activities ID I was filtering on. That's why we were getting all those extra things. All right, so let's go back to the big join. We're left outer joining both tables.

02:56:04Thanks, Cap. Okay, it's actually doing what I want. Now let's see if we can translate this nonsense into the active record selector. Which I had over here. This wants to be left out or join moderations on

...43msaid5860 hi im just trying to fix an issue with my kernel cuz its not recognizing the .img file...
I can't specify the on, can I? Can I say on two things? msaid5860 could u help?
Hey, MSaid. Welcome. I can't help you with that. But good luck.

02:57:08Fun. I don't think I'm allowed to do that, but it would simplify the where. And it would kind of put these things in the join, which is what I want. And then I could get rid of this not null thing.

...46Did that do what I wanted? No, because where's the moderations, right? Did I spell moderation? Oh, it's not plural. It's not plural. That's what's wrong. Aha. That's nicer. So then... drainiard yay progress
We can say these things together, left outer join moderations on item type equals moderation and item ID equals moderations.id left outer join mod notes on

02:58:50Yeah, item type equals mod node, and item ID equals mod nodes ID, where eitherโ€ฆ What is it? Actually, I thinkโ€ฆ It shouldn't be possible to have any record where it's both null unless the foreign key is broken. 403. So that was all of them. Yeah. Okay. And for handling the foreign key, I can make a checker for that.

03:00:00Just as a nitpicky thing, can I do this as two joins? Because then it's less to read. I don't remember. When you throw a string into joins it becomes. yeah. that's even better.

...56So then you can see the parallelism of it.

03:01:13It's not great that I have to say that, but I can actually say that.

...38Let's grab this query. Which, of course, has a line break issue. Come on. And then just limit. I would say where. activities.id is greater than 400. So we get the last couple rows. I just want to see the whole projection. Yeah, so this is, I don't know what Rails will do with this because now there's multiple columns named id and multiple columns named user id. Will we get anything useful out of that?

03:02:42activity dot myth item where mod activities dot id is greater than or equal to 400. well at least it's not overriding all the three. When I look at zero, one, and three, let's look at two. yeah so the alternate ids are not overriding but those attributes are just gone aren't they so if i said mass first item it's going to go and fetch the item which is the thing i want to avoid and if i said where user id equals 66 which is this test user right column user id is ambiguous so it could say moderations dot user id is 66 or mod notes user id is 66 And I get the ones for this user. But then if I'm just going to start iterating through these, I'm just going to get, I can't includes, can I? Oh, I can. Ooh. So I can preload. All right. So

03:04:58then if i go to ma's two item i get the moderation and no query no it queried again why did it query again all right this time it didn't

03:05:31Is there something about the way I accessed the variable? What caused it to reload? Because it clearly just ran the thing again. Let's try that again. Now the include should be in the model. So I see the includes. Yeah, I see it ran it again. And it ran it again. Because it's a relation. What if I smash it down to an array?

03:06:29Huh. drainiard I'm not familiar with rails but if its ORM is anything like sqlalchemy, you need to do the joins via ORM methods
So there's something happening about the query where Rails isn't recognizing that it filled its cache, but the actual items are fine when used. That's interesting. Not going to put that in the scope though, because I want to be able to tag those where's on. And I guess what I want is to be able to say, can I also use the nice interface of moderations user ID is 66 and mod notes user ID is 66.

03:07:37Now see, you think you can't eager load it, but you did eager load it. You fibber. Rails doesn't know what it's capable of.

...51That's funny.

...58But that does mean that this whole thing with the left outer joins is probably going to be a little brittle.

03:08:10I think I'm okay pushing it.

03:09:19call it user or user user all right well i'm getting back what i want so i guess i'm happy right

...50And that's positive, because I honestly half expected it to error, because there's now three fields named Create it at, but it. Actually, yeah, it ordered by the right table, so that's that's great.

03:10:17Activity user is showing user. Order is created at desk. And you know, now that we don't have to have two tables of 10, let's go nuts and make it 20. Wild and crazy, right?

...55What's this look like right now? Can we just leave?

03:11:05It's got to be a symbol. It doesn't exist. I just can't see what it looks like because I'm in the middle of editing it. I think the new note label will be clear enough. So let's. And then we can drop out. This. Because now it's one table.

...39Yeah, let's get the oh, man, I am already over time. Let's bookmark it.

03:12:01And then.

...07The last stuff that I did, that refactoring on the mod stuff, I think I can be done with that. Yeah, so let me throw this up and point out this will be last call for questions about stuff. You should throw them in right now because I'm going to wind down the stream and then on Monday for the stream-iversary. Yeah, and don't hang up because I am going to click the button to send everybody over to Chael Codes' channel. drainiard thanks for the stream!
Yeah, so we got this in. So we want to set it to the previous commit. I'm not going sideways. And I thought I got you to stop thinking of your upstream as origin.

03:13:22But it's not backwards.

...30Oh, I hadn't pulled in this. All of this stuff has to rebase onto main. Because when I started the stream, I hadn't pulled in the thing I had. All right, so let's run a fetch.

...50just to make sure we got everything all right and then see this is me still learning jujitsu and then we are going to rebase rebase this branch onto so like after which is b for no good reason i think let's check yeah ah it's a and b is before and after all right so we're gonna say rebase everything up here and i think it'll run down to the last common ancestor and we'll say after main that's the kind of linear history i like to publish And now bookmark set main to my parent. To my parent, yes. And then push. Yeah, jj get push main. Push dash b main. All right, let's say that. Yeah, see, why do you think it goes to origin?

03:15:28Told you the remote is GitHub. Let's go look at it on GitHub.

...42Good. So that's pushed up. And let's run deploy. So this takes about 30 seconds. And I am going to go ahead and type the command to send us all over to Chail Codes' channel, right? Sets. Raid Chail Codes.

03:16:13And I think I get some fancy GUI. I have to click through, which is tough because the cat is on the mouse. Okay, it actually erred because I included the app on her name, even though it auto-completed that.

...35Viewers are ready. All right, let's go say hi and be friendly. Thanks for hanging out. Take care.

...50did it go honest to god this interface i don't know if it's working or not oh twitch so now i'm trying to tune into my own stream so that i can find out no i don't think the raid works

03:17:41We'll try that again. I mean, I don't know what this thing. Oh, she's working on her rails out. Nice. So do I just click right now? Interface is sold to us.

03:18:17Yeah, there we go.