Typo Plugin : permalink with ID

Posted by Tim Connor Sun, 22 Oct 2006 21:17:00 GMT

Questions about what dynamic-scaffold-resource does arose, so I was going to write a post about that, as a warm-up for actually doing the documentation. But, then I got distracted by a blogging issue, and ended up solving that with another plugin.

As I mentioned in this post I’ve been wanting to keep Typo’s friendly permalink URL scheme, but mildly modify it to preface the title with the id, allowing for changing the title part of the permalink, but still have it match based on the id. Well, as I was about to write my other post, I noticed that one of the links that got out in the wild before I changed my permalink scheme was the 4th Google result for rails named routes. The result was pointing to a “no post found page.”

Well I did a temporary fix quickly with a little .htacces rewrite magic, but that made me more determined to actually have good fix along the lines I wanted of being able to find the article via an ID prefix, text changes aside.

So I checked out a copy of Typo trunk and messed around with it to see what it would take. I got the code working, after some exploration, and then started porting it to a plugin. Thus I know the functionality works, but it isn’t quite ready for release, as one of the two pieces is still just in the Typo code modifcation.

So what exactly does the tyo-permalink-with-id plugin do? It adds an after_create (since you don’t know the id until it after it has been saved to the DB) hook on the article to prefix the id to the title in the permalink (this is the part already moved into the plugin).

after_create do |article|
  article.permalink = "#{article.id}-#{article.permalink}" 
  article.save
end
It also adds some logic to the code that displays the article based on the permalink. If the full permalink (with ID) isn’t found, look for the article first by the ID prefix, and then by the whole permalink as title (smooth upgrading for your articles which predate this scheme). If the article is found either of those ways it redirects via a permanent-redirect/301, not a 302, since that is where it should really be to the proper permalink address. If it’s not found, it finally falls back to the standard Typo “post not found” message (which I want to upgrade next – make it give a link to the browse by date for that date).

def permalink
  article = this_blog.published_articles.find_by_permalink(*params.values_at(:year, :month, :day, :title))
  redirect_to article.permalink_url and return if article.nil? and article = Article.find_by_id(params[:title].to_i)
  redirect_to article.permalink_url and return if article.nil? and article = Article.find_by_title(params[:title])
  display_article(article)
end

So I just need to port that last bit over to the plugin, and we are good to go, and I’ll post an update. I’ll also be posting some bits I’ve learned in doing this. Actually these side-diversions from my main project are definitely helping my Rails and ruby knowledge, which will benefit that project.

DynamicScaffoldResource is Beta

Posted by Tim Connor Fri, 20 Oct 2006 06:14:00 GMT

As of 30 minutes ago, DynamicScaffoldResource hit 0.2 (tests implemented). All that leaves is documenting, trying to find an eaiser way to include the required Rails patch, and any bugs people find or fixes they suggest. It’s fully functional, though – I’m currently using it on a resource in a project under development.

Of course, having seen the code, I don’t know that I would exactly suggest this (or any of the Rails dynamic scaffolding) as a production solution or anything. Which is a shame, because with how much code is in common in newly RESTed controllers, it’d be nice to DRY them out.

Mocked out ActiveRecord for testing plugin

Posted by Tim Connor Fri, 20 Oct 2006 06:06:00 GMT

I mentioned this in my previous post, but to make my plugin easier to test I tried to make it not need to touch the DB, which was interesting to do, given that scaffold_resource is very much tied to a model. This was a big inspiration and this the final (as of now) result:

class Resource < ActiveRecord::Base
  @@count = 1
  def self.count() @@count end
  def self.columns() @columns ||= []; end
  def self.column(name, sql_type = nil, default = nil, null = true)
    columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default, sql_type.to_s, null)
  end
  def self.find(param)
    return param == :all ? [Resource.new{ |m| m.id = 1; m.name = 'bob' }] : Resource.new{ |m| m.id = 1; m.name = 'bob' }
  end
  def save() @@count += 1 and return true if valid? end
  def destroy() @@count -= 1 end
  column :name,          :string
end

Manually setting id in Rails 2

Posted by Tim Connor Fri, 20 Oct 2006 00:12:00 GMT

In testing DynamicScaffoldResource, I have been working on sort of mocking/overloading ActiveRecord so that it doesn’t touch the DB, so I can minimize how much it depends on the root Rails environment to test, since it’s a plug-in.


class Resource < ActiveRecord::Base
  def self.columns() @columns ||= []; end
  def self.column(name, sql_type = nil, default = nil, null = true)
    columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default, sql_type.to_s, null)
  end
  def self.find(param)
    return param == :all ? [Resource.new(:id => 1, :name => 'bob')] : Resource.new(:id: => 1, :name => 'bob')
  end

  column :id,            :integer
  column :name,          :string

  validates_presence_of :name
end
Well Rails treats the id as a special field, since it is. I tried letting it implicitely add it, and explicitely as above, but there was no way I seemed to be able to set it manually and access it (maybe the problem is prior to a save?), so my edit named route in the view wouldn’t choke (the show path had no problem with the nil, which I might not have caught for a while). While there is probably some way to open up access to the id column, this mailing list post opened up an alternative that works, just use:

Resource.new{ |m| m.id = 1; m.name = 'bob' }

User-friendly RESTful permalink

Posted by Tim Connor Wed, 18 Oct 2006 16:23:00 GMT

So I’ve taken to changing my permalinks ala: http://www.notsostupid.com/blog/2006/07/07/urls-on-rails/. Of course, Typo already has user-friendly slugs, but I am now prefacing the article id to the title, for the permalink. My thinking being it would take a minor patch to Typo to allow for this sort of routing, and suddenly I have the freedom to rename my article and permalink at will, without making old links obselete. I mean who hasn’t realized a glaring typo AFTER an article is published. Well, if one ever has readers (not me, of course ;)) then you can’t just go and correct it, without making potential links out there incorrect.

Yes, I realize this scheme isn’t actually RESTful, it just came up in looking into REST stuff, and has some potential advantages.

Dynamic Scaffold Resource Rails plugin is officially Alpha

Posted by Tim Connor Tue, 17 Oct 2006 23:44:00 GMT

My first Rails plugin, DynamicScaffoldResource has hit 0.1 – it now should handle all the basic REST actions almost identically to the generated scaffold_resource. The main difference is it uses the ActiveRecordHelper form() call to dynamically generate the forms, and auto-iterates over the columns on index and show, just like the offcial scaffolding. This is more fitting for the dynamic scaffolding than the blank form approach of the generator, which makes sense for that, since you will be filling that in manually.

If anyone is interested the subversion repository is up at http://svn.infosauce.org and trac is at http://trac.infosauce.org

It is still completely undocumented and untested, but those are the plans for the next release. Knowing what else needs to be fixed it probably won’t be before 0.4 or 0.5 before I’d say it’s public ready. For instance, it still requires you to have these patches applied.

My first contribution : a couple of patches toward dynamic scaffold_resource

Posted by Tim Connor Mon, 16 Oct 2006 16:17:00 GMT

I just submitted my first two patches to Ruby on Rails. I was thinking that I wanted something a certain way, and the best way to get that is contribute. I submitted these two “tiny” patches:

add options[:url] to form() in active_record_helper.rb – partially allows for RESTful call

add options[:method] to form() in active_record_helper.rb – partially allows for RESTful call

as they truly are tiny and might get applied. And of course, I submitted the tests, so my patches didn’t get tossed out immeditately.

I have to say trying to get Rails to pass its tests is a pain, and from the look of their ticket system, some of those might not be meant to pass yet (TDD). Anyways, I gave up on some of the minor tests that might not work on my system (Win32), and just made sure I did not break anything else, in making my changes. One I did that, it was actually pretty easy.

Then since the end goal I am aiming at is significantly larger, I submitted the following email to the core mailing list, instead of just jumping in and stepping on toes.

So I’ve RESTified a couple controllers, now, using the latest stuff in Edge and they don’t feel very-DRY. I realize that after they get more complicated they will need to be able to be stand-alone, but they are currently pretty wet. I considered working on an abstract REST controller, but then realized that dynamic scaffolding was almost all I needed. I just want to be able to not have to repeat myself until the controller diverges from the norm.

Now perhaps an abstract controller might be able to be figured out in such a way to allow for better TDD, but I think basically a copy of the current generated tests for scaffold_resource could just be dropped in test for those who want to do TDD, and the scaffolding could use updating if everything is supposed to move towards REST/CRUD.

I submitted a couple tiny patches to active_record_helper.rb form() to add options[:url] and options[:method] so that the ARH form could at least be called in the current REST style (since the scaffolding uses that form(), which was hard-coded to an old-style url :action =>), but wanted to ask here before proceeding further.

Am I completely off base here? If I want a dynamic scaffold_resource :model should I proceed and submit the patch? Should I just update the current scaffolding to use the new REST style, or make it scaffold_resource? What are the odds of this sort of thing getting applied? More likely given the push to REST, and since this would add another minor nudge? Should I make any other tiny patches needed to core, and then just make the rest a plug-in?

Tim

So nothing has been accepted yet, but my first patches are submitted at least. Yay!

Migrating Typo and b.settings['canonical_server_url'] bug

Posted by Tim Connor Thu, 12 Oct 2006 18:14:00 GMT

While setting up a new typo install on Dreamhost I hit a bug in the migrations, specifically 051_fix_canonical_server_url. Basically, if you run rake db:migrate to get the DB ready for typo, it chokes because it expects that you have already configured typo.

b.settings['canonical_server_url'].gsub(%r{/$},'')
fails because b.settings[‘canonical_server_url’] isn’t defined, but it’s easy enough to fix, just add unless b.settings[‘canonical_server_url’].nil? to the end of that line:

b.settings['canonical_server_url'].gsub(%r{/$},'') unless b.settings['canonical_server_url'].nil?

Why I like Markaby and JSON - they're Lisp

Posted by Tim Connor Thu, 12 Oct 2006 17:45:00 GMT

I just realized that the Markaby code I have been working with looked familiar for a reason, it very closely resembles Lisp code for generating HTML. There are some obvious syntactical differences (a few missing parens), for instance, but they are still remarkably similar.

And that got me thinking about my preference for JSON, and the fact that it isn’t too far from Lisp in concept (a data storage format that is actually valid executable code in its language) as well as syntax.

Maybe the Lisp zealots are right: the cutting edge of languages will slowly evolve into Lisp. Either that or the quip about you will have ended up writing a Lisp parser by the time you solve some of the same problems in your language of choice.

Of course, Rails is much, much easier to work with for creating web apps, so for now I’ll just be amused by the mini-Lispisms I find.

Markaby and Rails named routes and form_for 2

Posted by Tim Connor Thu, 12 Oct 2006 05:57:00 GMT

I’ve been getting back into programming full-time, instead of managing developers and fitting my own coding around that time as I could (read 18+ hour work days), by building a family project in Ruby on Rails. I’ve managed, maintained, and debugged a number of RoR projects, but this will be my first from the ground up full build. Now, of course, this is a perfect opportunity to go all out, use the bleeding Edge, and try and do everything right, which suits my perfectionist side just fine.

Part way through the first phases of the project, I come across Markaby and decide to switch away from ERb to that. It’s a way of doing your templating for Rails in pure ruby, which is nice for me, as my ruby needs more practice than my HTML, and it saves me from the verbosity of HTML.

Of course, a little later I come across another way to get a litle further out of the safe mainstream. While working on my functional tests (yes, not only am I learning Rails, I am learning TDD at the same time) of the verify :method => (to prevent GET requests from accessing destructive methods), I take the next step into territory that Rails Edge has been moving in and push further into RESTful stuff a little further. At the most basic this means using HTTP DELETE to destroy an object, instead of a form post. Of course, since browser don’t support DELETE, Rails has a reasonably sightly hack to let you have your back-end code be clean and handle a true DELETE and a slightly hacked form delete in the same way.

Well then I start going further and trying to make the next model I am working on fully REST accessible. This leads me to some of the newer stuff in Rails for that, the merging of simply resful plugin functionality into Rails. Well that and the kick-ass v2 Agile Development with Rails book lead me into using named routes in my form_for of my templates.

form_for :modelname, url => modelname_path...

Well this is where things get a little jinky. Markaby does all sorts of magic and assumes that most helpers called should be directly output to the HTML stream. This is great most of the time, but sometimes you don’t want this, like when said “helper” is a named route and outputting directly into the HTML at that point will not work with your form. Of course, they address this issue , in general. Well it doesn’t quite solve the problem of this specific usage. A commentor on the blog even asks a question about named routes. Unfortunately commenting is closed to move things to the new Markaby Trac, before there is 100% resolution.

So, at the risk of bugging the maintainers, I reopened an old ticket on the issue, and asked about it there. There is some mention of being able to use .to_s and that does work for me, but I hadn’t really seen it documented, and wanted to know if that was the official word on handling named routes. I’ll update here with the response, but for now this does work in Markaby:


form_for :modelname, url => modelname_path(@instance).to_s

Older posts: 1 ... 6 7 8