 I just have a quick question. This is a Ruby conference and not a Rails conference, but I'm just curious. How many here have played with Rails? Right on. How many do Rails programming professionally? Right on. This is almost a Rails conference, right? Anyway. We've been asked to do a live code review of a real Rails application. I'd like to thank Joel for giving this application to look at. It's always kind of frightening to have a large body of people look over your code and have someone else go over it and point out what could be done better. We really appreciate that. Should we just hop into it? Yeah. All right. So let's first pull up the community controller. Tell you the truth. We're not entirely sure what this application even does because we couldn't run it. We didn't have Postgres set up, so we couldn't do all that. But, so we're not looking at it from a, this application should have been written this way in order to do what it needs to do better. We're just looking at it from, this little snippet of code could probably be done differently to fit better with Ruby and Rails idioms. One thing that struck us is this kind of pattern shows up a lot where something is assigned and then if not, the first nitpick is unless is a more Ruby-ish idiom. If you're saying, instead of if not, you can say unless. Even better though, since he's just checking to see if that current tab is null or not, you can say and get rid of that whole second line. Okay, that's the cleaner idiom that you see. Secondly, here he's checking to see if offset is nil. And if it isn't nil, he does a two I on it, otherwise he sets it to zero. Fortunately, nil, two I, is zero. So that cleans that one right up. This one's a little hairier to pull into one line and you don't always wanna go for one liners anyway. Ultimately, all of this should really be pulled into the get communities method on the community controller. So you'd assign all that you just say instead of offset and so forth, you do params offset, params limit, params tab and so forth. And then you would just let the communities method determine what to do in the case that it's nil or whatever. There's a part in Kimbeck's small talk, best practice patterns, if any of you have read that, where he gives a tip on how you can approach refactoring your methods and determine where to decompose methods like what the dividing lines are. And his tip is that method, all of the things that happen in a given method should be in the same level of abstraction. So in this case we have the notion of communities, get communities, which is like the higher level thing that's ultimately happening. And then we have all these little implementation details about how the community is gonna be gotten, like setting the offset and the limit. And really in the controller, all you want is the higher level symbolics of what's happening. So it's really just get communities and you'd wanna make the data available to that to determine what communities to get so that you're not mixing up those two things and kind of context switching between the lower level and the higher level concepts. Let's do a search on that. Yeah, yeah, the difference, so does anybody know, except for Aira, the difference between, so he was saying when we were saying instead of doing params offset or zero or whatever, if params offset was nil, instead of doing two I, like we were recommending he would say do integer, which James just wrote. So does anybody know what the difference between dot two I and integer is? So how is it more strict? If you do two I on the string Marcel, it'll give you zero, but if you do integer on the string two I, it'll raise an exception, right? So in cases where it really matters that you're expecting either nil or an integer and you get something like a string, if that matters, if that distinction matters, using integer is better because an exception will be raised rather than just getting zero. It's like the pearl approach. It probably depends on what it was, like if you're, he said, so is that a choice that you would, is there Rails conventions for this or wouldn't you just deal with that kind of domain logic in a different layer, in a different way? And I say it probably depends on what the business rules are, but yeah, I wouldn't probably just be doing coercion right there in the controller. It would be implemented over in the model in some different way. So ultimately the story here is this would be refactored an entirely different way, but given the way it is written, there are better ways of doing it. It's actually more strict than that. If you have something like one Marcel and you do two I on it, you'll get a one and if you use integer, that would give you an error as well. Yeah, it's kind of the difference between time parse and date parse, right? So date parse is a lot more forgiving. One of them is more forgiving, but they're both retarded because if you do Marcel Lena, date parse Marcel Lena, it gives you some date. Clearly. I mean, it's not my birthday, so it's wrong. So ultimately the lesson is the controller shouldn't care how that is coerced. Looks as though all that stuff is setting up the view, actually. That's all data that's supposed to go to the view. It's not for finding the communities. It's setting up paging, which you should probably use that stuff up there, yeah. I guess it does depend on the limit. It was there a second ago. They were finding a total and they were finding what page and what the offset is and all that kind of stuff. Yeah. If this really is just about pagination, you start wondering like, why aren't you refacting this out into a library that ends up handling it? Yeah. So it should be put somewhere, probably not down into get communities because they don't care about that down in there. Right. The pagination is beyond that scope. Yeah. The app get communities in a separate method that returns the communities paginated. Yeah. Something like that. Something like that. Yeah. Well, let's just do a find with textmate so that we can jump to them directly. Oh, good. Yeah. You're a power user. And I'm not, obviously. Now, command shift F. I think we should just go in this order because we're not going to be able to locate. Sure. Yeah. So just a side note. Doing this helper and model stuff was an old way of doing dependency loading and all this stuff is obsolete now because it's just done automatically. For a certain time, you had to still use model user and declare a model if you wanted to store instances of that model in the session. Whether or not you should even do that is a different issue. I'm of the opinion that you should just be storing IDs and grabbing them when you need them. But you don't need to use either helper or model. That's just a small detail about Rails that is obsolete. I'm just going to bite you now. Yeah. Okay. This one. This is a method in the application controller protected. They do that. And it basically takes a file name and an image destination and does a bunch of image magic stuff on it to crop it. It really should belong in an object, a helper object in the lib directory because it's beyond the scope of the controller. The controller shouldn't care how to crop an image. It should belong to an image cropper or an image manipulator class that does that. And then any time you need it, you would just say imagecropper.cropimage and give you the parameters. The other thing about this is to plug Ken Beck's book again, he talks about method objects. When you have this big method that sets a lot of local variables, it's sort of starting to look like, hey, there's some state here that you need. If this was split across multiple methods, some of which were private, it would be even more reason to do this. But conceptually this isn't too complicated, but it would be far nicer to read if each little subsection of it was broken off into a more symbolically representative method that was intention revealing. So the ultimate API of invoking it would just be some class method, right? Like imagecropper.crop arguments. But the implementation would be nice small focused methods that had state and didn't need to pass around locals and stuff like that. So it would simplify the implementation as well as separating it out into the appropriate place. Just adding quickly, there's also a number of plugins that do cropping and stuff. Yeah. Since we're talking about the symbolic, since Marcel brought that up. Sure. Since Marcel brought up the symbolic aspect of bringing methods, making them more symbolic and more representative of what they're supposed to do, this is another place we noticed. What are you saying? If params finish, if params feeds, reading that code our first thought was what does that mean? What does params finish mean? What does params feeds mean? It's a lot clearer. Like if that's saying, if something's finished then you could have a method, you know, if something is finished, question mark. And then down somewhere else you would then wrap params finish inside of that. So that the code reads a lot more cleanly and you can tell the intention by looking at it. In this case, they're just checking the value of a parameter. So if the parameter is named well, then it might give you 80% of where you want to be. But thinking about problems in that more symbolic way in general will be more applicable in situations that aren't as clear cut as that. Basically, if everyone was here for Ares talk yesterday, the part where he had that code about like reaping zombies or whatever, that was, I think that's what you should ultimately aim for. To me that's like a great little snippet of archetypal idiomatic ruby where it's basically all symbolic representations. Yeah, that was brilliant. I loved that. Yeah. Phil Morgan reaped zombies. But it wasn't just that. I mean the whole thing was like that. Yeah. I mean ruby makes it so easy for your code to read like English. Obviously you don't want to go too far. Apple script I think is the wrong way to go that far. And there's a certain feeling you get in your tummy like, ah, this is too much in direction. It's not worth it. But most of the time at least one level of symbolics is nice because you also just sort of have it tucked away. I mean you can also take the approach as well. This is easy enough to read. I don't need a symbolic representation of it. But then the implementation gets a little bit trickier because you're adding another condition onto it. So at first it was just prams whatever. But then it becomes prams whatever and some other thing. And then at that point, after a certain point your brain has to parse these implementation details and it's no longer thinking of what they actually represent. Question? I noticed you guys use the ORs, the double OR and the double ampersand a lot. Do you have a thing against AND and OR? Well the binding is different. Yeah. So if I do foo AND, A and D, something else the result of that expression is going to be the object that was Boolean true. So like if foo is a string Marcel it's not going to return true, it's going to return Marcel. Whereas ampersand ampersand is going to return the Boolean value of the result of that expression. And a lot of times you'll have these weird masks shadowed. I mean you'll have these weird bugs shadowed because you're using AND rather than ampersand ampersand. And so although as a literature major I like AND because of the way it reads, I never use it because it's not worth it. Except for when the thing arrow was doing work. You could avoid it by using parentheses, right? But that's so much uglier than using... That's nasty. I just was curious about your preference. I mean sometimes it doesn't matter. Like in AIR's example where it was in a block the binding of that operator, the precedence of the operator isn't going to matter in that case. But especially when you're dealing with assignment or something or return, like if you say return hello and this that's not going to do what you expect. And this might be something with side effects where you don't actually care about the value like redirect to or something. So in general I'd recommend avoiding the AND word and using the ampersand ampersand. That's more predictable. There's a question up there. If you have a bunch of nested if statements you're almost inherently not object-oriented. Yeah, that's a bunch of if... Like else if to me is a smell. Nested if statements is a smell. Like you're not using polymorphism or whatever. Right. So you want to capture anything that you can in the structure of the objects around it rather than building procedural code and capture all the if statements and so forth. Yeah, right. I never feel comfortable almost never do else ifs. Almost never. Let's go back to the little flying thing unless you have something keyed up. I would go to idiomatic Ruby. Yeah, I think we covered that one. We can do this pass params tab thing. Yeah, we did that too. There's this, we can talk about that. This is back to that else if thing we were just talking about in fact. There's this thing in here where they set a flag, has errors to false and then they check to see if there's already a community with the given title. And if there is, they set has errors to true and set some message that they're going to explain the view. Otherwise they check to see, okay, is there a community by that name? If there is, they set the message and set has errors true. And then they come down and say, if it's a post, so they're doing post back there's no errors, then do something. Any time you're dealing with booleans and error handling, you really ought to step back and think about how you could use exceptions to do it. In other words, you'd throw all this into some sanity checking method or even into the community object itself. Yeah, there's clearly rules here that are being stated with these multiple conditions and there's different, and so ultimately there's this higher level concept that's being hidden by procedural implementation details. And so really it should be the responsibility of the higher level operation to raise the appropriate exception. And so rather than storing this state that's determining whether or not you're in an error state or not, you would just be raising and rescuing that in the controller. Yeah, so then down at the bottom of the controller you just have rescue community error. You define some custom exception that you're going to raise so that you don't wind up catching exceptions that you didn't mean to catch. Something, and then down here you would do your render whatever with the message from the exception that you want to render. It just, you don't have to worry about the else if stuff anymore because it's all encapsulated in the model. You're making your actions shorter, skinnier, and you're moving all that logic to the model, so. Yeah, in general, and James wrote a whole article about this on his blog, in general the style of organizing Rails applications that's really enjoyable for me is that I like designing the models. I like thinking about the behavior and the business rules and the entities inside of your domain and modeling all that stuff. And by modeling I mean writing code, not like playing with UML. It's really gratifying to spend time in that and create really nice, rich models. And then because of that the controllers become so dumb that they're not even interesting, they're just gratifying because of how little code you've written. Right, so for me controller actions should be like five lines at most. And they'll just be very declarative. They'll almost be like a DSL because the model has encapsulated all this stuff. You shouldn't really having to be jabbering with all these different conditions inside of the controller. The controller is just saying like say you're writing a chat, web chat application. You'll say like banish user if not allowed and then after that user enter room. And you just have these high level objects and you're just declaring what they're doing rather than having to parse what methods are being called on certain data structures and then infer what that could actually mean. We were working in a development shop and it was a fairly large Rails application. We were all foreign to Rails. It was a learning process to us. The first prototype was built and all the logic was thrown into the controller. And immediately in my head I went, wait a minute, we can't reuse any of this when we want to extend it to an API because it's put into the controller. The light that came into my head was the immediate knowledge of wow we really need to throw as much as this reusable code into the model that it relates to. And then build out what it could extend to in the library. And when we started realizing that, that's exactly what happened is the controller became skinny, dumb and then reusing the code was very simplistic. There's the reusable piece which is a really valid motivation but there's also the testing piece where if you have all these concerns inside of your controller you end up writing these huge fat functional tests and... They're really brittle. Yeah, they're really brittle and you have a lot more value if that stuff was broken up more nicely into the unit test. But also there's just sort of the cohesiveness of design. It just ends up being clearer what's going on when the controller is really just controlling stuff at a higher level. There's a question in the back. Yeah, well... Spans a couple of models. You know, it's incorporating information from a couple different models. Don't be afraid to create a model that doesn't descend from ActiveRecord. We've done that at 37 Signals for some things. We'll have a sign up controller that encapsulates the account and the user and the person record and all these things and it's just this kind of super model. Super model. It's this... Ironically, it's very beautiful. Just like a super model. But it's great at encapsulating that business logic that spans models. You said that's a controller or a model? You called it a controller when you first... It's a class. It's a model class, but it's a model that doesn't inherit from ActiveRecord. So... This is one... This is an example of a skinny controller with a default controller. Some of these actions have zero lines. It's great. Now, this isn't skinny because the models are helping. It's skinny because of other reasons. But this is what I like a controller to look like. One note. If you look at the implementation of action controller, there's like a process method which really just wraps the bulk of the request response loop. And if you look at it, the part where it does implicit rendering, you'll see that there's a condition that says this isn't a method missing, I think. If the controller doesn't have an action by the name that we're requesting, but there's a view that has that name, just render the view. So as a result, if you don't need to do any kind of controlling, if all that stuff is set up in a before filter or whatever, you don't actually need def about or any of these empty actions. But what I would recommend, initially I would just leave them out if I just had a view, but from a sort of maintainability point of view, it's nice to have all of your actions be listed there even if they're doing nothing. So what I've gone, what I've taken to do, what I have, what I do now, is I just do that. Just sort of self-documenting. That's a small tip that I'd recommend. And it's nice too because if later you decide you need more functionality there, it's nice to go. You don't need to remember what the action was called and try to remember how to get up. Question back here. And wouldn't you also need to have the method if you wanted to do authentication checking on that method? So if you didn't have the method, then you're before filters or wouldn't any filters firing? Yeah, they fire. Whether the method exists or not, before filters will always fire up until then the time it goes, before filters, now where's the action? If it can't find it, then it tries to find a view and if it finds the view it just renders it. Because that stuff's all controlled by the action name method, not by the execution of the action. Yeah. It's not doing like reflection. Action controller is actually pretty fun to dig through. It's a fun one to pop through. As opposed to action view. Right on. Okay. The question was the exist method I mocked out there quick. And his question was is that because it raises an exception? Is that my little convention? That's kind of what I've done. Any time it might raise an exception, I'll do a bang on it. Because it's not what I'm saying, does this exist? Yeah, I mean this exists. This exists or else kind of thing. Or actually I'm saying it doesn't exist or else. So maybe I misnamed it. But anyway, the point is if it's a query, like if it's supposed to return a boolean, then the question mark makes sense. It's supposed to be used that way. So I indicated that with a bang. That's just my convention. That's not necessarily a Rails or Ruby convention. But it makes sense for me. Quick question here. Do you have any advice for how to improve the flexibility of functional tests? We have an example from this code. Well, it's actually a unit test. But it applies to both. It's in the feed test So there's this notion of fixtures and Rails where you set up testing data and you'll end up, it's basically a hash, right? So you have a label for the testing data which describes what purpose it serves, what testing scenario it's applied to, and then you have the data, the testing data. All that stuff ends up being data in your database stored. And as part of your testing data you're setting IDs on all this stuff. So here where they're doing like feed find four, higher up it does feed find or get feeds one, and here find four. What the hell does four mean in this situation? What does one mean? The appropriate way to do this or excuse me, a better way to do this is Is this a model or a unit or a functional test? This is a unit test, but accessing stuff from your model happens just the same in functional tests. Or if you're passing, like in a functional test you would do like a get request for a functional test and an ID. So you could put four there or you could do the symbolic name that describes the data that you're testing. So this is a way to make your test far less brittle because you might need to actually change what the ID is of that record and it won't affect your test but it'll also make it easier to read and more maintainable for others and yourself. But it's just an extension of the strive for symbolics rather than implementation details. And another thing, I mean the striving for symbolics if you find yourself testing this a lot, get hello with a particular ID or get hello with something pull that into a helper method for your tests. What's the assertion? The cost of wrapping that stuff into a richer method is so low and the benefits are multivalent. I don't know what they are. Something like that. It's easy to make your own assertions. Another quick question with the exception handling. You wrote the exist bang. Are you recommending doing that over the default record validations? Validations are fine but this wasn't about, well I guess it was about uniqueness of a couple. In that case you might want to take a look validates uniqueness of, something like that and then save. In fact, along with the bang idea, I use save bang a lot more than I use just save because save bang will raise an exception if the validations fail and then in your action you just rescue active record and valid or whatever it's called and render your exception case right there. What's the advantage of doing that over just checking whether save succeeded or not? Well then you've got an if statement and we've already said those are evil. Let's look at this, wait the prams thing for the helper and the tabs in block helper. There's not. When you do save bang it's implicitly a valid bang, right? So you're saying rescue is better looking than if? Is that what you're saying? No, not if but like if, else, if, else. Got it. So if you're saying if this is valid do something else do something that gives me shivers. It's better to do if, food.save bang and then proceed with the assumption that it worked and then have a rescue clause down at the end somewhere. In my humble opinion. What are we looking for again? Yeah. Index is where it is. Maybe link to tab. Ah yes. So there's several issues here. The part we're looking at here is the current tab thing. So you need to set the class if it's the current tab and you also need it to link to a certain place and you need a label. Really a nice API for this instead would be. So if you just use a couple simple conventions which aren't too life-jackety or not life-straight-jackety then you can get all this stuff for free and have a much clearer, nicer API. The benefits too is that in looking around in the code it turns out that this exact same thing is used elsewhere. So ultimately you would extract and generalize this stuff into a partial or a helper that would generate the appropriate tabs for you and do the current tab stuff automatically. Also know by conventions the application to go to using a named route rather than just an action name. So here they're doing link to popular action index or whatever. So by just doing tab popular you'd be able to set the class if current tab was set and you'd also be able to link to the appropriate named route. So when you look at tab symbolically it's just saying tab popular and the fact that current tab needs to be set will be taken care of in the implementation of the helper because when you're thinking of tabs it's not the paramount concern. It's just the fact that there's a tab there. But also then when you look at the helper the helper itself has a more symbolic clearer representation because it has named routes and you could even encapsulate the current tab stuff into something a little more elegant so you're not coupling yourself to some instance variable for example. But once you start having those tab things and then in another place you also have those tab things you're duplicating yourself so you could wrap that into a partial and it'd be even clearer. But when you just have tab if you decide it's not worth the indirection of putting it into a partial then the duplication is at least minimized to tab whatever, tab whatever else. So anyway by throwing that stuff into a tab helper you're sort of fixing three problems and ultimately making it easier to read. Worry about that when it becomes an issue. So that's the road for it just in case. Seriously that's the road to madness. He was saying like the problem with taking this approach is that you're then having this coupling between the label and the location in the application. If you have any logic related to what tab you're on and you're using the label basically the name here is what the user sees. Or if you do any international work at all where you have multiple languages you have to have the code value of that tab and the label of that tab. But then at that point when it comes to so you start off with this sort of naive simple implementation and it works and then your boss or whoever or yourself your conscious says oh this needs to happen oh crap. Now you have this fundamentally better refactored helper that you'll then change the implementation of rather than changing the inline logic in the view anyway. This might not be the be all in doll but it's a more flexible starting point as those kinds of issues come up. In fact you actually it's not a challenge it's an incentive to refactor this. I agree with the refactoring I'm just talking about your example. Well he's just sort of writing it. I'm just saying because this is a pattern that's very very very very useful and it demonstrates the power of named routes in particular. So I just wanted to whip out that showed you how something like that works and how incredibly simple it can be to do. And you're right there may become times where the name is not sufficient to identify the rest of the information when that time comes add more information to your tab helper pass a few more parameters in. In general the fewer parameters you can give forces you to live with more conventions and as we've seen from Rails conventions can make your life a lot easier. So the more you can depend on conventions sorry I'm going to actually mention something about you anyway but then I'll let you ask your question. Another nice thing about conventions is that so yesterday I was talking to Aira and we were talking about O'Cammill and I was trying to convince him to get into Haskell instead of O'Cammill. But he was talking about how he'll be having he'll see code where people are writing recursive functions that themselves define functions which are recursive stuff like that. So like a recursive currying function which generates or anyway. Because you know that stuff blows my mind I can't conceptualize it you know it's paraphrasing. And I was saying yeah but you know I bet the people who are writing those aren't trying to envision all of the stuff that you're trying to envision your head because they automatically know like well there's the base case in this recursive function and there's just these automatic like neural shortcuts right. So that's in a less sophisticated sense one of the great benefits of conventions is that conceptually there's all this sophisticated stuff automatically that you don't even have to bring up into the foreground because it'll just using these conventions be implicit across your domain. So in any event the conceptual complexity you don't have to retain as much when you sort of know that things work in a certain way by convention that's clear. Sorry. So that the API doesn't change as opposed to changing the number of parameters because then I got to go back and change all the data. I think that's a really good approach in general. What he said is in a situation like this when I know that there's a really high likelihood that this method is going to be responsible for more things down the line I'll just he said I'll throw in an options hash even if I'm not using it yet and just like merge it on or whatever with some defaults because that makes it a lot easier to refactor it and enhance the behavior and that's a general standard to do but yeah so I would say there's this impulse to when you're implementing something say well I don't really need this right now but I'm just going to write something now because if I do need it later I can have it and so part of you says no shut up just do that later if you really need to but I think this is a case where if you're balancing whether or not it's worth it it's so cheap to just say last argument options empty hash and it makes it way easier to refactor like our poor man's way of doing keyword arguments which you don't have yet and when it's in the language we'll get that for free but that's a good point so then I wanted to ask you what it's really a philosophical question but this thing that you're handling right here is it's the part that makes me sick about Rails when I'm working with it which is not much so which is a whole ERB bag and what the problem that I have is that I was just talking to Dan about this is that when you're in the view and you're in ERB and you're mixing in Ruby I feel like I've opened the door into Perl which is to say you can write very beautiful Perl but it takes some program or discipline which is exactly what you guys are showing here so I mean you can factor these things out but then and I'm just asking for your opinion on this and your experience so the question though becomes then how far do you push this idiom in other words why not have your view be the page where the page is a helper they call it helpers it's like so it's just a philosophical thing well yeah this kind of stuff is being the sort of feeling out the limits of how far you should push this stuff out is becoming more and more of a question so one of the ways where this kind of issue is being mitigated and people are experimenting is with the notion of presenter patterns something where you'll end up refactoring it to helpers but then you have seven helpers that are interrelated it's really an object that you want to be able to encapsulate more and organize in and of itself and not mix it in with these other view concerns so yeah at a certain point you end up refactoring it even further and pushing it into custom view classes which are responsible for getting past a certain amount of data and then knowing how to represent some of that data so it ends up sort of being kind of modally an object that's receiving being composed of the model objects and knowing how to present them and also having access to the template to be able to do the presentation rather than being behavior on the model itself but is that sort of addressing what you're talking about pushing it into further layers of abstraction this page farther and farther up into helpers until it was nothing but one word and it's just where just in your experience it's obviously a personal thing that uses the finesse that you need to keep your views from looking like, you know, ASP and that's what the presenters end up sort of doing you'll be like person.form or whatever person.showform and show is really just proxying through a presenter or delegating to a presenter so are you saying that if you do have like a number of helpers that you think are interrelated and you're starting to think what is the next level the presenter is probably the way to go there Well, James has been playing around with one sort of way of implementing presenters and I've been playing around with another way of implementing it and I think he was excited about it and has since become less excited about it because of actually trying to use it and some of the limits of using it but there's an approach that I take which can be, it's really lightweight and simple which is basically just to create a class which has some set of some set of model objects and then the template object and then it just has a method missing that says if the template responds to this invoke it on the template so then you can essentially create a method object where you have the state and you can end up doing whatever view stuff you want because you have access to the template and I think that's not built into Rails the cost of implementing a class that just has a certain set of minimal contracts is really low and it pushes specific encapsulated concerns into their own presentation classes so it's some pretty low cost way of cleaning up more sophisticated sets of helpers and the extraction to do that is simple at first you're like, okay I don't need a class that's over engineered, I'm just going to write a couple helpers and you realize you're passing data across all these helpers and you need to add a section of comments that will say this is the helpers for this so that you can visually recognize where they are and then it's like okay, this is a class okay, thanks I wanted to show one more thing because we're kind of at a time this is a block helper thing the editable oh yeah, where was that not that I think it's further down in here is it in this one? if can edit so this is sort of weird in the controller that are magic flags and coupling yourself to that I think a nice pattern in this case is basically one of the approaches to when do I extract to a helper is you have conditional presentation logic so it's some condition that you want to encapsulate like if logged in question mark rather than if at sign user dot not nail or whatever so conditional presentation logic or repeated markup generation but in a kind of elegant way I think of encapsulating conditional presentation logic is you can build something called a block helper where in the same way that form4 if you all are using the new form4 you'll just say it's not erb equals form4 so it's not spitting it out it's form4 do so you're yielding to a block and stuff happening inside that block is a side effect is building is adding stuff into the view so you can encapsulate stuff like if can edit into a more abstract conditional block helper called editable and so what the actual code would look like here is oh you just had it show them the editable I guess right so instead of if can edit you just do editable do and let's do it let's implement that you implement it state of the world is some condition can become arbitrarily complex but if it's false this doesn't do anything right and so when you start doing if can edit and some other instance variable that I set and some other instance variable that I set A that's harder to parse in terms of the symbolics of what it means but B it also ends up being something you use all over the place when you start duplicating all that stuff and so you can wrap that inside of some method like if something if some predicate view stuff else or whatever but it's nice to just have the API of doing like admin content do and so you're basically just saying stuff inside of this block is admin content and whether or not to actually display it is right this is the reason why this is nice it's not just a matter of wrapping an if implicitly it's not just a matter of a different way of doing a condition it means you can also do like pre and post processing so in the case that it's true you can also do I always want to have this wrapped in a div so every time you have an admin section you're going to put the content that you want there if the current user is an admin but you also want to have a policy that that content is always wrapped in a div with a certain class and whatever other arbitrarily sophisticated thing you want to do which you don't want to have to include every time you're specifying admin content get it I mean collective yes so this block helper pattern is nice both for wrapping conditionals but also just for doing any kind of it's sort of like getting the yielding to a block thing where it does pre and post processing but applying that to a view context era concat is just a shorthand for doing underscore erb out and then concatting it onto this thing because the way like if do we have a if you go to some template and do what is it erb-x chat what is it you can't just you couldn't call it with block or and block right there you both have to call it and pass the binding seems like you could just pass the block oh the binding is needed in order to get the erb out variable but he's just saying you should just be able to pass the block so we could we could implement concat so that if it just had a block yeah that would be better that's our problem not your problem yeah era is saying you should just be able to do something like this and have it automatically do call and binding yeah so this is like a rails issue not a client it's like an internals rather or that's probably that would be nicer good call era but for people who are just interested we can look at what and you can just get an rhtml template and do erb-x on the command line would ask for the command line or whatever community index that's right so is it this erb-x so erb is like a hack to the max it just has this magic underscore thing that you call concat on and then it just ends up sticking all the string on it and then it evals it that's how it's just an eval and templating system so our concat is just a like slightly friendlier wrapper around underscore erb but it's like it's so it's a way of um it's like a side effect where you're actually modifying the template yeah I think we're out of time that's it