New Contact Feedback Plugin

Posted over 7 years back at Mephisto - Home

James Crisp wrote a nifty Contact Feedback plugin for Mephisto for the new Thoughtworks Studios site. The plugin looks nice, and fills a common need in Mephisto. Also, the Thoughtworks Studios site is extremely well-done. I had seen it before, but didn’t realize it used Mephisto. Major kudos to James Crisp and Thoughtworks!

For anyone that asks: it looks like the main difference between this, and my own feedback plugin is that mine doesn’t send emails. It stores them in the DB and lets you browse in the admin. Nice since your inbox doesn’t get the spam, but I’ve been finding that I often forget to check it :)

Customising controllers - new API

Posted over 7 years back at The Hobo Blog

One of the nice things about Hobo is that you never have to write the seven boilerplate actions to get a basic CRUD controller (index, show, new, create, edit, update and destroy). The downside is that if you need to tweak the behaviour of one of those actions, there’s no code in your controller to tweak.

I’ve been addressing that issue by adding hook points, e.g. you can define create_response and invalid_create_response in order to override Hobo’s default responses. I’ve never been totally happy with that approach though - the number of such hooks is bound to grow until there’s a rather complex little API in there, which we certainly don’t want.

Today I’m having a go at a different approach. The index action in Hobo’s model controller is now as follows:

def index
  hobo_index
end

The hobo_index method (which is protected), can also be passed a bunch of parameters, so you could override index in your controller like this:

def index
  hobo_index :page_size => 10
end

Through parameters like that, you can customise pretty much everything. A common requirement is to include some eager loading in the ActiveRecord find:

def index
  hobo_index :items => Post.find(:all, :include => :comments)
end

Another trick - if you pass the items as a proc, the find will happen in a scope that handles pagination for you. (UPDATE: After some digging I’ve come across the idea, which I thoroughly agree with, that this is really an abuse of with_scope)

Baaad idea

def index
  hobo_index :items => proc { Post.find(:all, :include => :comments) }
end

So here’s the new way to achieve the same (and I renamed the :items parameter)

Good idea

def index
  hobo_index :collection => paginated_find(:include => :comments)
end

I think this approach is going to be easier to learn, while giving you a fine-grained choice between having Hobo do things for you, and having custom control.

Customising controllers - new API

Posted over 7 years back at The Hobo Blog

One of the nice things about Hobo is that you never have to write the seven boilerplate actions to get a basic CRUD controller (index, show, new, create, edit, update and destroy). The downside is that if you need to tweak the behaviour of one of those actions, there’s no code in your controller to tweak.

I’ve been addressing that issue by adding hook points, e.g. you can define create_response and invalid_create_response in order to override Hobo’s default responses. I’ve never been totally happy with that approach though - the number of such hooks is bound to grow until there’s a rather complex little API in there, which we certainly don’t want.

Today I’m having a go at a different approach. The index action in Hobo’s model controller is now as follows:

def index
  hobo_index
end

The hobo_index method (which is protected), can also be passed a bunch of parameters, so you could override index in your controller like this:

def index
  hobo_index :page_size => 10
end

Through parameters like that, you can customise pretty much everything. A common requirement is to include some eager loading in the ActiveRecord find:

def index
  hobo_index :items => Post.find(:all, :include => :comments)
end

Another trick - if you pass the items as a proc, the find will happen in a scope that handles pagination for you. (UPDATE: After some digging I’ve come across the idea, which I thoroughly agree with, that this is really an abuse of with_scope)

Baaad idea

def index
  hobo_index :items => proc { Post.find(:all, :include => :comments) }
end

So here’s the new way to achieve the same (and I renamed the :items parameter)

Good idea

def index
  hobo_index :collection => paginated_find(:include => :comments)
end

I think this approach is going to be easier to learn, while giving you a fine-grained choice between having Hobo do things for you, and having custom control.

General Genetic Algorithms for Ruby (gga4r) release 0.9

Posted over 7 years back at Spejman On Rails

General Genetic Algorithms for Ruby (gga4r) is a library for executing generic algorithms easily.

Only 3 steps are needed in order to work with gga4r:

  1. Choose a clase to evolve and define for her the fitness, combine and mutate methods.

  2. With an array of last defined class instances (initial population), create a GeneticAlgorithm object.

  3. Call GeneticAlgorithm's evolve method as many times as you want.


More info:

Kathy and Chris sitting in a tree...

Posted over 7 years back at Wood for the Trees

Really hot stuff this Kathy Sierra nonsense. Oh wait, a tasteless pun. Is everyone going to hate me now? Grow up!

I usually don’t wade into political debate because it is full of morons, but it’s the middle of the night and I’m really bored. In fact, annoyed. Like I was with Rails 1.2 (how’s that for continuity!)

Who I Sympathise With and Who I Support

I’ll give, frankly, my sympathy to Kathy (who is manic, slightly weak-willed, has some good ideas, some other ideas a little dodgy, and has all the traits of a modern American woman, for good or ill) but I give my serious support to those calling for uncommon sense. This situation is so cliched and yet has slipped passed a few people I respect that I’m going to kill some time here and point out that Dave Winer, who I never heard of before, is right to be skeptical. He made just one mistake: he wasn’t confident enough to spell out why others should be. Please, please stop fuelling the media. It’s just evil.

So, without further ado, the train of thought:

The gist of my view:

  • Threats and offensive comments on the internet are newsworthy, therefore not worth my time (unless I’m killing it).
  • Being a high-profile speaker in the IT world will have its share of ‘acerbic’ commentary
  • Being a blogger will get you the same
  • Putting your details online is just dumb
  • Men abuse each other using sexual language, but we’ve got used to it over the last five millenia and now think it’s kind of amusing

For example, the Bile Blog, which is an institution in slagging shit off. Thankfully it still exists. Poor Hani doesn’t get a BBC article because the Bile stays strictly asexual. But in a post-feminist, emasculated society, you can get really hated for saying anything remotely gender-specific. I’m sorry, but I don’t buy that. It’s proscriptive and - for the same reason I think I should be able to take a pie or bottle of water on a plane even at the risk of being blown up - molly-coddling. Anyone with some self-respect and decency should feel a little spineless and self-indulgent if they coddle Kathy. A mild dose of feminist support is fine, because I like women to be people rather than objects, but indulging in the mass opinion is, well, like getting a labotomy. Some of the points Kathy made were, of course, right: it’s pretty sick some of those things she cited. However, it’s not rocket science to see she is also over-reacting and taking the majestic ‘blogosphere’ with her. Her avid fans who want to hang her are most likely infantile, possibly autistic twits in the middle of nowhere, with the social graces of a louse.

What’s the truth?

The situation is as plain as a Bulgarian pin-up. Kathy takes the net seriously and flips out. Her readers, which are many, believe her. Others who see those believe her think the readers must be right because there are so many of them. A few people are skeptical and they are lampooned, making the case even stronger that Kathy is being persecuted. It goes to the media, which means it must be true!

Qualifications

Please realise that there are minorities of both idiots and intelligent people in the real world just as much as on the internet, with one slight difference: ‘law’ isn’t firmly established online. That’s quite literally fantastical, but true, and we should cherish that infinite freedom. I don’t want a jackboot in my face for telling someone online they can stick their ideas up their cuntflap or hang by their genitals, nor see a person cuffed and imprisoned for behaving as amorally as Sodom. Your morals and theirs may not mix, but that’s neither here nor there. Morality is for religion, not law and the internet is lawless.

All this lovely lawlessness is because of its anonymity. People use that anonymity out of cowardice (yes) but also safety. Uh huh, that’s right. The louse should be protected too, all the way up until he actually clubs Kathy over the head and brings her back to his cave. That’s real free speech. It’s not pleasant sometimes, but it’s very, very important to realise how extreme an idea it is (the original one, not the hashed up piece of shit served by ‘democracies’ around the world).

Summary

Kathy thinks threats are equal to actions, for which she loses my support, though I still hope she pulls out of her mire of self-doubt and back into posting for her readers. Maybe during that period she should read some comforting Spinozan ideas on epistemology and semantics.

Resorting to qualified (that is, reasoned) support and sympathy is quite different from just jumping on the wagon of lynchers, to use Chris Locke’s own words.

Just as a reminder, this is where enforcing morality leads. BBC are really getting lazy; they’ve got two articles on mass hysteria. But they are the news and cater to the lowest common denominator. It’s quite different when respected, intelligent individuals are the cause of the stir. I only hope some of you will give it a little more consideration next time and do the intelligent thing: be as long-winded as I am. Then no journalist could bear reading it.

Kathy and Chris sitting in a tree...

Posted over 7 years back at Wood for the Trees

Really hot stuff this Kathy Sierra nonsense. Oh wait, a tasteless pun. Is everyone going to hate me now? Grow up!

I usually don’t wade into political debate because it is full of morons, but it’s the middle of the night and I’m really bored. In fact, annoyed. Like I was with Rails 1.2 (how’s that for continuity!)

Who I Sympathise With and Who I Support

I’ll give, frankly, my sympathy to Kathy (who is manic, slightly weak-willed, has some good ideas, some other ideas a little dodgy, and has all the traits of a modern American woman, for good or ill) but I give my serious support to those calling for uncommon sense. This situation is so cliched and yet has slipped passed a few people I respect that I’m going to kill some time here and point out that Dave Winer, who I never heard of before, is right to be skeptical. He made just one mistake: he wasn’t confident enough to spell out why others should be. Please, please stop fuelling the media. It’s just evil.

So, without further ado, the train of thought:

The gist of my view:

  • Threats and offensive comments on the internet are newsworthy, therefore not worth my time (unless I’m killing it).
  • Being a high-profile speaker in the IT world will have its share of ‘acerbic’ commentary
  • Being a blogger will get you the same
  • Putting your details online is just dumb
  • Men abuse each other using sexual language, but we’ve got used to it over the last five millenia and now think it’s kind of amusing

For example, the Bile Blog, which is an institution in slagging shit off. Thankfully it still exists. Poor Hani doesn’t get a BBC article because the Bile stays strictly asexual. But in a post-feminist, emasculated society, you can get really hated for saying anything remotely gender-specific. I’m sorry, but I don’t buy that. It’s proscriptive and - for the same reason I think I should be able to take a pie or bottle of water on a plane even at the risk of being blown up - molly-coddling. Anyone with some self-respect and decency should feel a little spineless and self-indulgent if they coddle Kathy. A mild dose of feminist support is fine, because I like women to be people rather than objects, but indulging in the mass opinion is, well, like getting a labotomy. Some of the points Kathy made were, of course, right: it’s pretty sick some of those things she cited. However, it’s not rocket science to see she is also over-reacting and taking the majestic ‘blogosphere’ with her. Her avid fans who want to hang her are most likely infantile, possibly autistic twits in the middle of nowhere, with the social graces of a louse.

What’s the truth?

The situation is as plain as a Bulgarian pin-up. Kathy takes the net seriously and flips out. Her readers, which are many, believe her. Others who see those believe her think the readers must be right because there are so many of them. A few people are skeptical and they are lampooned, making the case even stronger that Kathy is being persecuted. It goes to the media, which means it must be true!

Qualifications

Please realise that there are minorities of both idiots and intelligent people in the real world just as much as on the internet, with one slight difference: ‘law’ isn’t firmly established online. That’s quite literally fantastical, but true, and we should cherish that infinite freedom. I don’t want a jackboot in my face for telling someone online they can stick their ideas up their cuntflap or hang by their genitals, nor see a person cuffed and imprisoned for behaving as amorally as Sodom. Your morals and theirs may not mix, but that’s neither here nor there. Morality is for religion, not law and the internet is lawless.

All this lovely lawlessness is because of its anonymity. People use that anonymity out of cowardice (yes) but also safety. Uh huh, that’s right. The louse should be protected too, all the way up until he actually clubs Kathy over the head and brings her back to his cave. That’s real free speech. It’s not pleasant sometimes, but it’s very, very important to realise how extreme an idea it is (the original one, not the hashed up piece of shit served by ‘democracies’ around the world).

Summary

Kathy thinks threats are equal to actions, for which she loses my support, though I still hope she pulls out of her mire of self-doubt and back into posting for her readers. Maybe during that period she should read some comforting Spinozan ideas on epistemology and semantics.

Resorting to qualified (that is, reasoned) support and sympathy is quite different from just jumping on the wagon of lynchers, to use Chris Locke’s own words.

Just as a reminder, this is where enforcing morality leads. BBC are really getting lazy; they’ve got two articles on mass hysteria. But they are the news and cater to the lowest common denominator. It’s quite different when respected, intelligent individuals are the cause of the stir. I only hope some of you will give it a little more consideration next time and do the intelligent thing: be as long-winded as I am. Then no journalist could bear reading it.

Sometimes It's The Little Things...

Posted over 7 years back at zerosum dirt(nap) - Home

With this latest RoR project, we decided for the first time to take a RESTful approach. It’s taken me much longer than it should have to come to terms with what that actually meant, but after suffering through the change of mindset, I really do have to say that it feels right. I’m down, you’ve won me over.

That said, there are always little implementation details that annoy the hell out of you. Little, trivial, stupid things. Things that you know you shouldn’t waste precious breath complaining about, things that you annoy your friends about until they ignore you. Things like the use of the damn semi-colon to delimit custom actions for resources in a URI, instead of our old friend the slash.

And then came Changeset 6485, which made everything once again right with the world. Thank gawd that’s over. Now I can get back to being productive :-).

Episode 11: Refactoring User Name Part 2

Posted over 7 years back at Railscasts

Testing and refactoring go hand in hand. Refactoring is all about improving code without changing its behavior. Testing is all about making sure you don't change the behavior while you are improving the code.

Second screencast posted in Flash

Posted over 7 years back at The Hobo Blog

A few folk seem to be having trouble with the audio in the second screencast. We’ve just posted a rough Flash version as a stop-gap solution. The quality is a bit naff but it’s better than not being able to hear anything!

If anyone can recommend a nice tool for converting QuickTime to a good quality backwards-compatible Flash movie, please let us know in the comments. Thanks!

Second screencast posted in Flash

Posted over 7 years back at The Hobo Blog

A few folk seem to be having trouble with the audio in the second screencast. We’ve just posted a rough Flash version as a stop-gap solution. The quality is a bit naff but it’s better than not being able to hear anything!

If anyone can recommend a nice tool for converting QuickTime to a good quality backwards-compatible Flash movie, please let us know in the comments. Thanks!

Episode 10: Refactoring User Name Part 1

Posted over 7 years back at Railscasts

Learn how to clean up your code through refactoring. This episode will show you how to move code from the view into the model to remove duplication and simplify the view.

Episode 9: Filtering Sensitive Logs

Posted over 7 years back at Railscasts

Are you accepting sensitive user data? Passwords, credit card numbers, etc. By default, Rails stores all submitted parameters in plain text in the logs. This episode will show you how to filter this sensitive input so it doesn't show up in the log file.

Is Mephisto Dead?

Posted over 7 years back at Mephisto - Home

Is Mephisto dead? I see much more Typo activity recently than Mephisto. It’s the same with most open-source Rails apps. Development is cyclothymic – people get excited in the beginning, then slow down (or completely stop) – probably work on some “for pay” project, then get excited again (when the paid project is completed maybe?), then slow down again and so on. Substruct, Collaboa, Typo, RadRails, Project RIDE-ME, Active Merchant and many others… I don’t see this happening in Java world and I miss the “die hard” Java enthusiasm in the Rails community. —Nikolay Kolev, comments on previous article

Nope, it’s been on hold since the end of 2006. Mephisto has a tiny development team, and we’re both busy trying to launch a web service. We have 0 funding, so we’ve basically been devoting our “OSS project time” (and “sleep time”) towards Lighthouse instead.

I’ve found that most of the ‘successful’ open source projects have some source of real funding. Either there’s a company that needs the product enough to fund/hire the team, or they make enough through custom installs or commercial versions. Other than a handful of small consulting gigs and some donations, Mephisto has been purely a labor of love for us.

What’s going on right now:

  • I’m entertaining the idea of extending to the core team, but I don’t feel there’s been anyone that seems interested in devoting the time.
  • However, I’m thinking seriously of extracting a few things out as “official plugins” and opening up access on those small areas. The current candidate is XML-RPC support.
  • There’s a small 0.7.4 update with a few security issues and annoying bugs fixed
  • There’s an edge version with some notable new features (plugin admin, plugin support for RHTML/HAML templates, and soon: a multi-site admin)
  • Once Lighthouse goes out of beta, we’ll have an official bug tracker.
  • Core team doesn’t haven’t to mean “svn commit access” either. It could also mean “ticket overlord” or something.
  • DNS info is currently being transferred to moniker…

However, Justin and I are committed to keeping Mephisto true to its roots. We’re not going to turn it into another bloated CMS, or a community blogging tool. It’s also not a kickstart to your rails app development. It’s strictly going to remain a kick ass publishing tool. Further features/integration should be done through the power of hyperlinks or APIs (exposed through custom Liquid drops).

What belongs in the model?

Posted over 7 years back at The Hobo Blog

It’s a regular post-a-thon :-)

I just came across this old post on the Rails blog about Streamlined.

Of particular note:

I really like their approach of using separate UI classes instead of contaminating the model classes with administrative concerns.

That’s DHH, and I wholeheartedly agree. But then Hobo doesn’t have the “separate UI classes”. In fact Hobo does ask you to add extra metadata to your models which is then used in constructing the views.

Have I slipped up? I don’t think so…

Firstly Hobo doesn’t need “UI classes” because DRYML is powerful enough that we can configure everything to our hearts content in mark-up. As I said in my talk at the Skills Matter RoR exchange, it’s like the difference between an app with a preferences dialogue (UI classes where you set a bunch of options) and an app which is scriptable (DRYML).

Secondly, I don’t think I’ve added any metadata to the models that doesn’t belong there. Notice I say “think”. Coming across that post has made me think that I should really review this. So let’s do it – right now :-) fires up Hobo model extensions in trusty Emacs. Let’s make sure all the model extensions really belong there.

Before we start though, how do we decide what belongs in the model and what is merely an “administrative concern”. Is it a clear boundary or a grey one? I have a simple trick I sometimes use to help clarify this design challenge. When the coming Command Line Renaissance happens, and you’re building the fashionable new command-line interface for your app, will you still need this behaviour? If yes, it probably belongs in the model. If no it probably doesn’t. It’s an OO thing. Is this an innate part of the behaviour of the object you are modelling? Is it just something that you need to put this object on the web? Notice that this is a more subtle point than asking “is this a user-interface issue?”. Think about the models in a blog app. It’s all user-interface! The thing only exists in the first place because people want to read the blog!

Bottom line - there will always be grey areas. Some things will be absolutely not appropriate for the model, some will obviously belong in the model, some will be tricker.

OK so lets tour the Hobo model extensions and make some calls.

Permission system

You don’t have to do much coding with Hobo before you realise that modelling the permissions of your various objects is a very central and fundamental part of modelling your domain. To me this very clearly belongs in the model.

I guess you could say that Hobo makes the user model special, and in doing so extends the meaning of modelling to include modelling the rules governing what users are allowed to do to what. I think this has been a huge win and is an idea that could be taken a lot further.

An interesting question though: are these permissions innate to the models themselves, or could we imagine having a different set of permissions for different contexts? Pluggable permissions. Hmmm. How about a concise yet powerful rule-based DSL for declaring permissions? Sheesh - so many ideas so little time…

Extended type declarations.

Hobo lets you say

set_field_type :content => :html

If you then do, e.g.

Post.find(:first).content.class
=> Hobo::HtmlString

(That’s just a pretty much empty subclass of String BTW.) OK this one’s easy. That’s a model concern. No question.

Default order

set_default_order "created_at desc"

That order will then be used in your index pages. There’s a kind of asymmetry in ActiveRecord here – you can specify the default order for has_many collections, but there’s no way to specify a default order for a top-level find(:all). So we’ve really just balanced things out. Model concern.

Never show

never_show :password

The word “show” immediately cries out “user-interface issue!”. In fact this declaration is just a short-hand for something you could do anyway with viewable_by?. So if the permission system belongs in the model, so does never_show.

Creator attributes

set_creator_attr :author

This tells Hobo that the author attribute should be automatically set to the user that creates the object. On the web this means the currently logged-in user for the session from which the object was created. In another context it might mean something else. Again this idea follows naturally from the decision to model users as something special. To me this does belong in the model.

Search columns

set_search_columns :title, :content

This tells Hobo which columns to include in the built-in search feature. This is a bit like writing custom find methods on your models. We already have the magic methods like find_all_by_title_and_content. What we’re doing here is highlighting a particular query as special in some way, which to be honest feels a bit dodgy. Special from what point of view? From the point of view of your web-app? I can see this possibly moving out of the model.

Display name

If your model has an attribute display_name, this is used as the default text for the object in links and such-like. It’s also very useful for logging, and for debugging, and would certainly get re-used in your command-line UI. My feeling is that a display-name is an innate part of a thing, and so this does belong in the model.

OK that’s about it. There are a few other extensions but they’re so obviously part of the model layer that they’re not worth mentioning. So it was only really set_search_columns that was called into question.

The overall feeling I’ve got from this exercise is that the decision to model users as something special, something that has permissions, has lead to a lot more stuff going into the model than might otherwise. I don’t think this is at all wrong, but in asking these questions, some lights have gone on and I can see some advantages of moving this stuff into a separate place. I just wish those ideas didn’t have to get pushed to the bottom of a veeery long to-do list…

What belongs in the model?

Posted over 7 years back at The Hobo Blog

It’s a regular post-a-thon :-)

I just came across this old post on the Rails blog about Streamlined.

Of particular note:

I really like their approach of using separate UI classes instead of contaminating the model classes with administrative concerns.

That’s DHH, and I wholeheartedly agree. But then Hobo doesn’t have the “separate UI classes”. In fact Hobo does ask you to add extra metadata to your models which is then used in constructing the views.

Have I slipped up? I don’t think so…

Firstly Hobo doesn’t need “UI classes” because DRYML is powerful enough that we can configure everything to our hearts content in mark-up. As I said in my talk at the Skills Matter RoR exchange, it’s like the difference between an app with a preferences dialogue (UI classes where you set a bunch of options) and an app which is scriptable (DRYML).

Secondly, I don’t think I’ve added any metadata to the models that doesn’t belong there. Notice I say “think”. Coming across that post has made me think that I should really review this. So let’s do it – right now :-) fires up Hobo model extensions in trusty Emacs. Let’s make sure all the model extensions really belong there.

Before we start though, how do we decide what belongs in the model and what is merely an “administrative concern”. Is it a clear boundary or a grey one? I have a simple trick I sometimes use to help clarify this design challenge. When the coming Command Line Renaissance happens, and you’re building the fashionable new command-line interface for your app, will you still need this behaviour? If yes, it probably belongs in the model. If no it probably doesn’t. It’s an OO thing. Is this an innate part of the behaviour of the object you are modelling? Is it just something that you need to put this object on the web? Notice that this is a more subtle point than asking “is this a user-interface issue?”. Think about the models in a blog app. It’s all user-interface! The thing only exists in the first place because people want to read the blog!

Bottom line - there will always be grey areas. Some things will be absolutely not appropriate for the model, some will obviously belong in the model, some will be tricker.

OK so lets tour the Hobo model extensions and make some calls.

Permission system

You don’t have to do much coding with Hobo before you realise that modelling the permissions of your various objects is a very central and fundamental part of modelling your domain. To me this very clearly belongs in the model.

I guess you could say that Hobo makes the user model special, and in doing so extends the meaning of modelling to include modelling the rules governing what users are allowed to do to what. I think this has been a huge win and is an idea that could be taken a lot further.

An interesting question though: are these permissions innate to the models themselves, or could we imagine having a different set of permissions for different contexts? Pluggable permissions. Hmmm. How about a concise yet powerful rule-based DSL for declaring permissions? Sheesh - so many ideas so little time…

Extended type declarations.

Hobo lets you say

set_field_type :content => :html

If you then do, e.g.

Post.find(:first).content.class
=> Hobo::HtmlString

(That’s just a pretty much empty subclass of String BTW.) OK this one’s easy. That’s a model concern. No question.

Default order

set_default_order "created_at desc"

That order will then be used in your index pages. There’s a kind of asymmetry in ActiveRecord here – you can specify the default order for has_many collections, but there’s no way to specify a default order for a top-level find(:all). So we’ve really just balanced things out. Model concern.

Never show

never_show :password

The word “show” immediately cries out “user-interface issue!”. In fact this declaration is just a short-hand for something you could do anyway with viewable_by?. So if the permission system belongs in the model, so does never_show.

Creator attributes

set_creator_attr :author

This tells Hobo that the author attribute should be automatically set to the user that creates the object. On the web this means the currently logged-in user for the session from which the object was created. In another context it might mean something else. Again this idea follows naturally from the decision to model users as something special. To me this does belong in the model.

Search columns

set_search_columns :title, :content

This tells Hobo which columns to include in the built-in search feature. This is a bit like writing custom find methods on your models. We already have the magic methods like find_all_by_title_and_content. What we’re doing here is highlighting a particular query as special in some way, which to be honest feels a bit dodgy. Special from what point of view? From the point of view of your web-app? I can see this possibly moving out of the model.

Display name

If your model has an attribute display_name, this is used as the default text for the object in links and such-like. It’s also very useful for logging, and for debugging, and would certainly get re-used in your command-line UI. My feeling is that a display-name is an innate part of a thing, and so this does belong in the model.

OK that’s about it. There are a few other extensions but they’re so obviously part of the model layer that they’re not worth mentioning. So it was only really set_search_columns that was called into question.

The overall feeling I’ve got from this exercise is that the decision to model users as something special, something that has permissions, has lead to a lot more stuff going into the model than might otherwise. I don’t think this is at all wrong, but in asking these questions, some lights have gone on and I can see some advantages of moving this stuff into a separate place. I just wish those ideas didn’t have to get pushed to the bottom of a veeery long to-do list…