JavaScript and URL helpers need some love regarding best practices

7 views
Skip to first unread message

Clemens

unread,
Jul 7, 2008, 10:13:21 AM7/7/08
to Ruby on Rails: Core
Folks,

my original intent for this post was to promote a patch that I
submitted to Lighthouse because Pratik marked it as invalid and told
me to raise the issue here if I found it to be important. Please find
the ticket here: http://rails.lighthouseapp.com/projects/8994/tickets/517-link_to_remote-should-behave-like-remote_form_for.

However, I've pondered the issue over the last few days and I think
the root of the problem is actually way deeper than I originally
thought. I think, Rails' JavaScript helpers and URL helpers need a
certain amount of refactoring for one really simple reason: Pretty
much everywhere, Rails follows best practice approaches and advocates
a really clean and professional way of "doing things right". Two
exceptions to that rule are parts of the JavaScript helpers and URL
helpers.

Let me be a little bit more specific about issues that I think should
at least be considered:
- Like I said in the ticket, link_to_remote should populate the href
by default to provide a sensible fallback.
- submit_to_remote should be renamed or at least aliased to
button_to_remote just for the sake of being consistent with link_to/
link_to_remote.
- link_to/link_to_remote helpers should at least raise some kind of
notice when used with :method => :post/:put/:delete. Links shouldn't
be used to post/put/delete on a server. Yes, I know that it actually
wraps the whole thing inside a form, but still it's not a good idea.
The fact that potentially "destructive" actions should be handled with
a button should definitely be advocated.
- Not strictly related to the helpers: While I think that mostly
beginners use the scaffold feature, I feel that it still should
reflect best practices. Therefore, the delete link should be made into
a button.

Now while most if this stuff isn't an issue for me personally (and it
probably neither is for you guys), I feel that there's definitely room
for improvement. If I was to decide, I'd totally remove all
*_to_remote stuff from the core and force people to write their
JavaScript by hand and/or use lowpro. But I think, the above things
would be quite easy to implement without being a harsh change.

I kept this post short by intention in order for you to really read
it, but of course I've got some more ideas regarding these helpers.
I'd be more than happy to provide patches if you agree with me that
this is an issue worth being addressed.

Please let me know what you think.

Best,
- Clemens

Nik Wakelin

unread,
Jul 7, 2008, 6:11:50 PM7/7/08
to rubyonra...@googlegroups.com
Hi Clemens,

Isn't this the kind of thing that the UJS for Rails plugin
(http://ujs4rails.com/) already does?

Cheers,

Nik

--
Nik Wakelin
munky...@gmail.com

Clemens

unread,
Jul 7, 2008, 8:04:35 PM7/7/08
to Ruby on Rails: Core
Nik,

unfortunately, IMO it hardly is. First and foremost, UJS4Rails has
been unmaintained for more than 1 1/2 years for a simple reason: Dan
and Luke think that JavaScript should be written separately from the
app anyways. I'd have to say that I totally agree.

As I mentioned in my first post, IMO it would probably be best to just
totally remove this stuff from Rails because it kinda hides bad
practice behind some framework code. In most areas, Rails evangelizes
best practices and opinions by making it more work for the programmer
to break the rules (think of set_table_name, for example). But in the
case of these helpers it's actually less work to break the rules (or,
rather, guides - speaking of unobtrusive javascript) than to follow
them.

Especially those folks new to Rails (and probably not all that
experienced in web development in general) may be led astray where we
could easily guide them down the right or at least better way than the
current one. I'm not saying that Rails should be more newbie-friendly
- IMO the barriers of entry have already become too low if you take a
look at the questions asked at RailsForum or WWR. What I'm saying is
that Rails, to me, is a whole lot of good practices and rules and it
should be consistent in that way without any exceptions - not even
something as "humble" as the helpers.

Anyways, I'd love to hear more opinions on the topic.

Best,
- Clemens

On Jul 8, 12:11 am, "Nik Wakelin" <munkywre...@gmail.com> wrote:
> Hi Clemens,
>
> Isn't this the kind of thing that the UJS for Rails plugin
> (http://ujs4rails.com/) already does?
>
> Cheers,
>
> Nik
>
>
>
> On Tue, Jul 8, 2008 at 2:13 AM, Clemens <clem...@railway.at> wrote:
>
> > Folks,
>
> > my original intent for this post was to promote a patch that I
> > submitted to Lighthouse because Pratik marked it as invalid and told
> > me to raise the issue here if I found it to be important. Please find
> > the ticket here:http://rails.lighthouseapp.com/projects/8994/tickets/517-link_to_remo....
> munkywre...@gmail.com

Michael Koziarski

unread,
Jul 8, 2008, 3:07:38 AM7/8/08
to rubyonra...@googlegroups.com
> As I mentioned in my first post, IMO it would probably be best to just
> totally remove this stuff from Rails because it kinda hides bad
> practice behind some framework code. In most areas, Rails evangelizes
> best practices and opinions by making it more work for the programmer
> to break the rules (think of set_table_name, for example). But in the
> case of these helpers it's actually less work to break the rules (or,
> rather, guides - speaking of unobtrusive javascript) than to follow
> them.

I'll probably get in trouble for this, but I don't think that
unobtrusive javascript has yet to obtain the status of undeniable best
practise that you seem to be ascribing to it. The current helpers are
a pragmatic solution to what is otherwise an incredibly frustrating
job, and the code they generate may be 'obtrusive' but it works just
fine.

The specific case you mentioned in your patch sounds interesting but
I'm not sure that the assumption of being able to make non-AJAX to the
ajax url is a valid one. <a href="/people/1"> isn't the same thing as
a link which submits a DELETE request to the same URL.

> Especially those folks new to Rails (and probably not all that
> experienced in web development in general) may be led astray where we
> could easily guide them down the right or at least better way than the
> current one.

What are the current practical problems which the existing helpers cause?

> I'm not saying that Rails should be more newbie-friendly
> - IMO the barriers of entry have already become too low if you take a
> look at the questions asked at RailsForum or WWR.

I strongly disagree with this, while it may be satisfying to feel
superior about people finding it hard to get started, that's not the
way successful communities behave. The barriers to entry should be
*lower* not higher.

--
Cheers

Koz

Sandofsky

unread,
Jul 8, 2008, 3:14:35 AM7/8/08
to Ruby on Rails: Core
I think *_to_remote belong in a plugin. I can't remember the last time
I used one.

Nik Wakelin

unread,
Jul 8, 2008, 3:39:02 AM7/8/08
to rubyonra...@googlegroups.com
@Sandofsky:

views dir of project number 1 (irb) :

>> Dir["**/*.rhtml", "**/*.html.erb"].inject(0) { |total, file| total += `grep -c "link_to_remote" #{file}`.to_i; }
=> 29

views dir of project number 2 (irb):

>> Dir["**/*.rhtml", "**/*.html.erb"].inject(0) { |total, file| total += `grep -c "link_to_remote" #{file}`.to_i; }
=> 36

Would seem not everybody feels the same :)


(ps my unix-fu is not strong, so I might have messed those up...)

--
Nik Wakelin
munky...@gmail.com

Clemens

unread,
Jul 8, 2008, 5:06:20 AM7/8/08
to Ruby on Rails: Core
Koz,

thanks for the statements.

> I'll probably get in trouble for this, but I don't think that
> unobtrusive javascript has yet to obtain the status of undeniable best
> practise that you seem to be ascribing to it.  The current helpers are
> a pragmatic solution to what is otherwise an incredibly frustrating
> job, and the code they generate may be 'obtrusive' but it works just
> fine.

You're probably right about getting in trouble, I already feel the
accessibility folks will come kicking and screaming if they hear about
this! ;-) But seriously: A little proactivity wouldn't hurt here -
after all, Rails also created the whole Convention Over Configuration
buzz, wasn't it? It may well be that it can also give birth to a
_real_ unobtrusive javascript movement that really influences the way
people think about accessibility.

> The specific case you mentioned in your patch sounds interesting but
> I'm not sure that the assumption of being able to make non-AJAX to the
> ajax url is a valid one.  <a href="/people/1"> isn't the same thing as
> a link which submits a DELETE request to the same URL.

Absolutely right. As I said, I wrote the patch and the short post that
goes with it a couple days ago and reflected on it before starting
this discussion. I mentioned in my first post here that the programmer
should probably get an error message or at least a warning when trying
to use a "harmful" method such as delete in a link_to_remote because
it really should be a button (i.e. a form). If you can safely assume
that POST/PUT/DELETE are always handled by forms, pages generally
degrade more gracefully for people with JavaScript disabled. With the
current way, it doesn't - if you have a link with POST/PUT/DELETE and
a standard-REST action (e.g. /users or /users/1) it won't work with
JavaScript disabled. Instead of POST /users, people will get the index
action, and instead of PUT/DELETE /users/1, people will be given the
show action.

> What are the current practical problems which the existing helpers cause?

I think it's not so much a practical problem. IMO it rather is one of
those "little big problems" on a higher level.

Little story from one of my projects here: I'd tell the client that
I'll prepare a little prototype for them to see where we are going.
They'll then try the prototype and ask "Why doesn't delete work? It
always shows me the product page!". Well, guess what - they had
JavaScript disabled. When I told them to enable it because the
prototype needs JavaScript enabled, we got into a mini-fight about
this because one of the requirements for the projects was that the
page should degrade gracefully for people with JavaScript disabled.

As I said earlier, it's not so much about the current functionality
being a problem but more about the (IMO) better solution standing
right in front of us and (so far) being ignored.

> I strongly disagree with this, while it may be satisfying to feel
> superior about people finding it hard to get started, that's not the
> way successful communities behave.  The barriers to entry should be
> *lower* not higher.

I knew while I was typing that very sentence that I might get in
trouble for saying it or at least kick off a discussion because what I
said can easily be misunderstood. I had already written an answer to
that one but I've deleted it a few seconds ago to not kick of the
argument about that because I think the matter at hand is way more
important than the question of how high or low the barriers of entry
should be! ;-)

Cheers,
- Clemens

Michael Koziarski

unread,
Jul 8, 2008, 7:17:34 AM7/8/08
to rubyonra...@googlegroups.com
> You're probably right about getting in trouble, I already feel the
> accessibility folks will come kicking and screaming if they hear about
> this! ;-) But seriously: A little proactivity wouldn't hurt here -
> after all, Rails also created the whole Convention Over Configuration
> buzz, wasn't it? It may well be that it can also give birth to a
> _real_ unobtrusive javascript movement that really influences the way
> people think about accessibility.

I just don't think it's something we should be proactive about.
Making the ajax case that much harder to theoretically get
accessibility benefits doesn't seem like something we should be doing.
If there's a way for us to make extend the helpers to make it easier
to add fallback cases, then I'd be happy to hear about those. But if
it's just a question of either:

* Hand Code and be accessible
* use helpers and don't be

Then I think we can just leave the helpers as is and people who feel
strongly about it can start a community talking about how to avoid the
helpers, get some best practises brewing etc.

> As I said earlier, it's not so much about the current functionality
> being a problem but more about the (IMO) better solution standing
> right in front of us and (so far) being ignored.

Given how widely used the current fuctionality is, then we'd need to
see much better adoption of the better solution before we could do
something like this.

If something easier, and more accesible emerges then we can go for it,
but personally I definitely prefer to use link_to_remote over link_to
with some class then inject the ajax functionality onload.

--
Cheers

Koz

James H.

unread,
Jul 8, 2008, 9:28:06 AM7/8/08
to Ruby on Rails: Core
IMHO make the whole JavaScript package, as it currently stands, a
plugin. This would be a wonderful step towards having a Prototype,
jQuery, MooTools (etc.) package for Rails. The situation with Merb
and JavaScript is quite wonderful: pick your own and run with it.
There's no helpers, no RJS equivalent or anything. I like this
approach personally.

James H.

Pratik

unread,
Jul 8, 2008, 10:22:19 AM7/8/08
to rubyonra...@googlegroups.com
On Tue, Jul 8, 2008 at 2:28 PM, James H. <james....@gmail.com> wrote:
>
> IMHO make the whole JavaScript package, as it currently stands, a
> plugin.

There is absoltely no reason/explaination to do so. And I don't see it
happening. Many of us use those helpers in most of the projects, and
it works for us like a charm.

> This would be a wonderful step towards having a Prototype,
> jQuery, MooTools (etc.) package for Rails. The situation with Merb
> and JavaScript is quite wonderful: pick your own and run with it.
> There's no helpers, no RJS equivalent or anything. I like this
> approach personally.

Rails is not forcing you to use those helpers or RJS.

Lack of feature is not a feature. If Rails, in any way, is making it
difficult to implement those helpers/rsj in plugins for other js
libraries, solution is for Rails to provide hooks and make it simpler
to write such plugins. Patches welcome :)

--
Cheers!
- Pratik
http://m.onkey.org

Clemens

unread,
Jul 8, 2008, 10:55:17 AM7/8/08
to Ruby on Rails: Core
> Given how widely used the current fuctionality is, then we'd need to
> see much better adoption of the better solution before we could do
> something like this.
>
> If something easier, and more accesible emerges then we can go for it,
>  but personally I definitely prefer to use link_to_remote over link_to
> with some class then inject the ajax functionality onload.

I see where you're coming from. But I think we somehow lost a little
track from what I posted originally. I said that if I was to decide I
would extract the whole thing from the core but I also said that
that's unlikely to happen. Instead, I gave 4 quick suggestions for
improvements so that the current functionality (mostly) stays in place
and that the generated code degrades more gracefully. I understand
you're hesitant to completely remove a widely used feature - but what
do you think of my 4 concrete suggestions?

@James:
I totally love that idea but we'd definitely need to have an extra
abstraction layer like the AbstractAdapter for databases to provide
the possibility of framework-agnostic RJS for at least the most
important bits and functions. And personally I doubt that it can be
easily achieved because of the way the RJS generator uses
method_missing. But we could maybe take a closer look at it.

Michael Koziarski

unread,
Jul 8, 2008, 12:45:53 PM7/8/08
to rubyonra...@googlegroups.com
> I understand
> you're hesitant to completely remove a widely used feature - but what
> do you think of my 4 concrete suggestions?

Heh, good point

> - Like I said in the ticket, link_to_remote should populate the href
> by default to provide a sensible fallback.

I'm not sure that this *is* a sensible fallback though, given that it
won't work on resource routes it seems like most new apps wouldn't
benefit even a little from this. The link would go somewhere but not
where it said it would. This sounds more frustrating than just
hitting the #. The documented example seems pretty good in this case?

> - submit_to_remote should be renamed or at least aliased to
> button_to_remote just for the sake of being consistent with link_to/
> link_to_remote.

An alias sounds good.

> - link_to/link_to_remote helpers should at least raise some kind of
> notice when used with :method => :post/:put/:delete. Links shouldn't
> be used to post/put/delete on a server. Yes, I know that it actually
> wraps the whole thing inside a form, but still it's not a good idea.
> The fact that potentially "destructive" actions should be handled with
> a button should definitely be advocated.
>
> - Not strictly related to the helpers: While I think that mostly
> beginners use the scaffold feature, I feel that it still should
> reflect best practices. Therefore, the delete link should be made into
> a button.

I'm not convinced here, while I follow the reasoning that links
should be safe to click, and things which look like links should also
be safe, the pattern is so widely used in our industry I don't think
that putting our collective fingers in the dike will really gain us
much.


--
Cheers

Koz

Sandofsky

unread,
Jul 8, 2008, 1:27:38 PM7/8/08
to Ruby on Rails: Core
> Lack of feature is not a feature.

I think it is. Otherwise we'd have ActionWebService, pagination, and
acts_as_list in core.

Sujal Shah

unread,
Jul 8, 2008, 1:37:14 PM7/8/08
to rubyonra...@googlegroups.com
Wasn't pagination widely used when it was pulled out? How about
auto_complete? in_place_editing?

Sujal

Michael Koziarski

unread,
Jul 8, 2008, 1:52:48 PM7/8/08
to rubyonra...@googlegroups.com
>> Lack of feature is not a feature.
>
> I think it is. Otherwise we'd have ActionWebService, pagination, and
> acts_as_list in core.

ActionWebService and pagination were unmaintained with better
alternatives out there (REST and will_paginate). acts_as_list was a
close call but each of the other acts was unmaintained and essentially
broken, leaving one in there seemed unreasonable.

auto_complete was a tiny tiny wrapper around scriptaculous
functionality and in_place_editing was too restrictive and tightly
coupled.

Either way, there's no reason to remove those features except for some
ascetic sense of satisfaction which could be drawn. If you don't like
them you can just stop using them. There's no impact with having them
there for applications which don't use them.


--
Cheers

Koz

Sujal Shah

unread,
Jul 8, 2008, 2:23:57 PM7/8/08
to rubyonra...@googlegroups.com
I don't have a strong opinion here, but look at what you just said:

Pros for keeping helpers: Lots of projects use them

Pros for removing actionwebservice, pagination, etc.: unmaintained,
better alternatives exist (e.g. will_paginate) or can be made easily
(e.g. auto_complete)

The reasons for the proposed patch are "the functionality isn't great"
plus that it promotes accessibility, not just for screen readers but
for things like search engines. That's actually my most important
concern...

It sounds like the opposition is mostly that there isn't an
alternative/better implementation for the js helpers. So, let me ask
a different question: would everyone be more receptive to removing the
javascript helpers if an alternative existed? The UJS plugin was a
decent idea, and the patches attached to the ticket here are not bad
either. Or, is it that removing them is off the table, period? (I can
imagine arguments in favor of having a default JS plugin, but I'm not
convinced by any of them)

Sujal

Jan De Poorter

unread,
Jul 8, 2008, 2:46:16 PM7/8/08
to rubyonra...@googlegroups.com
I like the idea of extracting the javascript helpers and the
javascript files to a plugin. That way we can have a PrototypeJS
plugin, a jQuery plugin, a YUI plugin, which all provide the same
default helpers (Kind of the way ActiveRecord provides connectors to
MySQL/Postgres/...)

It would be great to be able to use the JS library that I fancy, but
with the helpers we all love.

regards,
Jan De Poorter

Michael Koziarski

unread,
Jul 8, 2008, 3:00:06 PM7/8/08
to rubyonra...@googlegroups.com
> I like the idea of extracting the javascript helpers and the
> javascript files to a plugin. That way we can have a PrototypeJS
> plugin, a jQuery plugin, a YUI plugin, which all provide the same
> default helpers (Kind of the way ActiveRecord provides connectors to
> MySQL/Postgres/...)
>
> It would be great to be able to use the JS library that I fancy, but
> with the helpers we all love.

Don't we already have this with things like jrails?

http://ennerchi.com/projects/jrails

If there are hooks or assumptions in our stuff that would make this
kind of plugin easier, then I think we could take patches for that.

--
Cheers

Koz

DHH

unread,
Jul 8, 2008, 5:08:31 PM7/8/08
to Ruby on Rails: Core
Just to chime in with my 5 cents (yeah, that's right, I just paid an
extra three! ;)).

1) I like button_to_remote as an alias for submit_to_remote.

2) I don't think the JS helpers should be a plugin at all. Rails has
always been about including a default answer to most common questions
at the infrastructure layer. Following the same argument, you could
debundle Active Record to allow for ORM alternatives, debundle Active
Resource for API alternatives, and so on. Soon you'd end up with
something that wasn't Rails. But as Pratik and Koz said, we should
totally make it trivial for people who want to do stuff like jrails to
make it so. Just like it's easy to add in your own template engine if
ERb/Builder doesn't float your boat.

3) Requiring all post/delete actions to be buttons is a personal
choice that you're more than free to make for your project. It
wouldn't fly with my designers at 37signals. Rails shouldn't be
dictating how the UI of an application should look or feel.

4) I agree with koz's analysis of the fallback of link_to_remote. We
have an even better way currently where you can set :url in the html
options and thus get a different fallback.

5) It's already possible to write unobtrusive JS with Rails. No one is
being forced to use link_to_remote and friends. If you like to write
your JS by hand, by all means do. But until there's an unobtrusive
answer with as much comfort and ease of use as the current obtrusive
approach, I don't see them going any where. I personally don't really
care about un/obtrusive. Or actually, that's not fair. I do care on
the "that'd be nice" level, but I'm not willing to trade much if any
developer comfort to get that.

Anthony Richardson

unread,
Jul 8, 2008, 7:58:41 PM7/8/08
to rubyonra...@googlegroups.com
This has been an interesting discussion. I don't have a strong opinion either way as I don't use the helpers or prototype/scriptaculous.

However, if you did want to make the current helpers unobtrusive, with backwards compatibility to current behaviour, couldn't you have the helper output a form in the HTML with javascript that executes removing the form and replacing it with the link and javascript as currently outputted by the helper.

So if a user goes to the page with javascript turn on they see exactly the same as they currently would. If they go there with javascript turned off they see a button.

Regards,

Anthony Richardson

James H.

unread,
Jul 9, 2008, 12:17:35 AM7/9/08
to Ruby on Rails: Core
> There is absoltely no reason/explaination to do so. And I don't see it
> happening. Many of us use those helpers in most of the projects, and
> it works for us like a charm.

[...]

> Rails is not forcing you to use those helpers or RJS.

The notion that there's huge chunks of Rails that may or may not be
used or are being needlessly loaded makes me squirm a bit.

James

Clemens

unread,
Jul 9, 2008, 3:25:48 AM7/9/08
to Ruby on Rails: Core
> 1) I like button_to_remote as an alias for submit_to_remote.

I've just posted a patch to
http://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/581-button_to_remote-aliases-submit_to_remote

> 3) Requiring all post/delete actions to be buttons is a personal
> choice that you're more than free to make for your project. It
> wouldn't fly with my designers at 37signals. Rails shouldn't be
> dictating how the UI of an application should look or feel.

Correct me if I'm wrong but a little CSS can make a button look like a
link and even behave like one (including a hover effect). I've only
tried it in Safari and FF3 for the moment but I think I remember that
it worked in IE6/7 just fine.

> 4) I agree with koz's analysis of the fallback of link_to_remote. We
> have an even better way currently where you can set :url in the html
> options and thus get a different fallback.

I know that but you seem to misinterpret my intent. All I was
proposing was a sensible default in the event that the user has
JavaScript disabled. I made this suggestion because I'm a good boy ;-)
and I use link_to_remote almost exclusively for GET requests where the
URL of the link would mostly be the same as for the AJAX request.
Question to everyone: Would it make sense to only default the :href
attribute to the value of :url if the link_to_remote handles a GET
request but leave it at "#" for POST/PUT/DELETE since they're likely
to be wrong anyways?

----------------------------------------------------------------------------------------------------------------

> 2) I don't think the JS helpers should be a plugin at all. Rails has
> always been about including a default answer to most common questions
> at the infrastructure layer. Following the same argument, you could
> debundle Active Record to allow for ORM alternatives, debundle Active
> Resource for API alternatives, and so on. Soon you'd end up with
> something that wasn't Rails. But as Pratik and Koz said, we should
> totally make it trivial for people who want to do stuff like jrails to
> make it so. Just like it's easy to add in your own template engine if
> ERb/Builder doesn't float your boat.

So how about the following idea:
We should abstract the current functionality and create an
AbstractJavaScriptGenerator that (maybe) provides common functionality
sits in as a parent for PrototypeGenerator, JQueryGenerator,
MooToolsGenerator, etc. In the config, we'd then have something like
config.action_view.javascript_framework = :whatever that defaults
to :prototype. Both, view helpers and RJS, should then use the methods
of the respective generator.
Moreover, we'd probably need to move each framework into its own
subdirectory in /public/javascripts and then modify the
javascript_include_tag :all to first load /public/
javascripts/:framework and then (non-recursively) load all other files
in the root.

If you guys agree to this (especially the core team), I'd start
thinking about that and maybe start implementing it next week. I'd
totally love if someone else cared to join me in the effort.

> 5) It's already possible to write unobtrusive JS with Rails. No one is
> being forced to use link_to_remote and friends. If you like to write
> your JS by hand, by all means do. But until there's an unobtrusive
> answer with as much comfort and ease of use as the current obtrusive
> approach, I don't see them going any where. I personally don't really
> care about un/obtrusive. Or actually, that's not fair. I do care on
> the "that'd be nice" level, but I'm not willing to trade much if any
> developer comfort to get that.

Very true, but I think, Rails should make it easier for people to do
unobtrusive JS as well.
How about making it configurable like my other suggestion? We could
have something like config.action_view.use_unobtrusive_javascript =
true that modifies *_to_remote in that it removes the onclick/onsubmit
event and instead adds a default CSS class (e.g. "remote", but maybe
also configurable) so we can easily add our unobtrusive JS layer to it
(using lowpro or whatever). That way, we're backwards compatible and
satisfy most people's needs that don't care about unobtrusive JS while
the unobtrusive folks could take a shortcut and use link_to_remote
instead of link_to with :class.
IMO that would be a quick win and I'd be happy to implement it as
well.

- Clemens

Joe

unread,
Jul 9, 2008, 4:41:02 AM7/9/08
to Ruby on Rails: Core
> Correct me if I'm wrong but a little CSS can make a button look like a
> link and even behave like one (including a hover effect). I've only
> tried it in Safari and FF3 for the moment but I think I remember that
> it worked in IE6/7 just fine.

Another possibility is to have button_to_remote actually use a
<button> tag. button tags can be styled nicely and can have inner
html content. It may even be sensible to make button_to work like
this as well and change the current to submit_to. One issue I recall
that needs to be handled differently with a button is the form's
action url. Anything after ? is ignored, so any parameters need to be
added as hidden fields in the form.

Just a thought.

Joe

Michael Koziarski

unread,
Jul 9, 2008, 4:52:23 AM7/9/08
to rubyonra...@googlegroups.com
> The notion that there's huge chunks of Rails that may or may not be
> used or are being needlessly loaded makes me squirm a bit.

Methods never called are hardly going to break the bank on performance
or memory usage. There's about a billion other things that should be
higher up your squirm list.

--
Cheers

Koz

Michael Koziarski

unread,
Jul 9, 2008, 4:57:23 AM7/9/08
to rubyonra...@googlegroups.com
> Correct me if I'm wrong but a little CSS can make a button look like a
> link and even behave like one (including a hover effect). I've only
> tried it in Safari and FF3 for the moment but I think I remember that
> it worked in IE6/7 just fine.

Wouldn't this defeat the entire purpose of *not* using a link. The
rationale as I understand it is 'links should be safe to click'. If
it looks like a link, acts like a link, but still isn't safe, then
we're worse off than with the current implementations. It still
surprises people but it depends on crazy css stuff.


--
Cheers

Koz

Clemens

unread,
Jul 9, 2008, 5:08:33 AM7/9/08
to Ruby on Rails: Core
> Wouldn't this defeat the entire purpose of *not* using a link.  The
> rationale as I understand it is 'links should be safe to click'.  If
> it looks like a link, acts like a link, but still isn't safe, then
> we're worse off than with the current implementations.  It still
> surprises people but it depends on crazy css stuff.

Definitely - I was actually just trying to make a point that you *can*
make a button look like a link and still conform with the general
consensus that non-GET actions should be put in a form rather than a
link. I should probably learn to not comment on every minor nuance but
instead focus on the more important stuff! ;-) The other 4 comments I
wrote on David's comments IMO are actually way more important, so I
guess we should focus on them. And I'll try to shut my pert mouth and
try to focus on the topic as well - I promise! ;-)

Michael Koziarski

unread,
Jul 9, 2008, 5:22:58 AM7/9/08
to rubyonra...@googlegroups.com
> Question to everyone: Would it make sense to only default the :href
> attribute to the value of :url if the link_to_remote handles a GET
> request but leave it at "#" for POST/PUT/DELETE since they're likely
> to be wrong anyways?

Try a patch for this and see what people think. It sounds good enough
if the implementation isn't too hairy.

> If you guys agree to this (especially the core team), I'd start
> thinking about that and maybe start implementing it next week. I'd
> totally love if someone else cared to join me in the effort.

I don't think we need to add anything quite that complicated to
actionpack. We bundle prototype and support it with some helpers etc.
Whatever faults prototype may have choosing something is better than
making it a configuration option which needlessly confuses people who
just want an ajax form.

If there's anything which is currently difficult to replace with a
simple plugin, then we can investigate it. But given the good job the
jrails guys have done, I don't think we need anything here.

> IMO that would be a quick win and I'd be happy to implement it as
> well.

I've heard rumours that sam stephenson was thinking around ways to
make those helpers nice and unobtrusive by default. If we can have
unobtrusive code that's just as simple (i.e. one helper call) as the
obtrusive kind, then I say we just go down that path. But again, I'm
not aware of any clear best practise in that space that we could latch
on to.

> - Clemens
> >
>

--
Cheers

Koz

DHH

unread,
Jul 9, 2008, 10:24:22 AM7/9/08
to Ruby on Rails: Core
> > 1) I like button_to_remote as an alias for submit_to_remote.
>
> I've just posted a patch tohttp://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/58...

Applied (with button_to_remote being the primary, submit_to_remote
being the alias). Thanks!

> > 3) Requiring all post/delete actions to be buttons is a personal
> > choice that you're more than free to make for your project. It
> > wouldn't fly with my designers at 37signals. Rails shouldn't be
> > dictating how the UI of an application should look or feel.
>
> Correct me if I'm wrong but a little CSS can make a button look like a
> link and even behave like one (including a hover effect). I've only
> tried it in Safari and FF3 for the moment but I think I remember that
> it worked in IE6/7 just fine.

That seems to defeat the purpose of the change. Switching one hack for
another. I'm -1 on this.

> > 4) I agree with koz's analysis of the fallback of link_to_remote. We
> > have an even better way currently where you can set :url in the html
> > options and thus get a different fallback.
>
> I know that but you seem to misinterpret my intent. All I was
> proposing was a sensible default in the event that the user has
> JavaScript disabled. I made this suggestion because I'm a good boy ;-)
> and I use link_to_remote almost exclusively for GET requests where the
> URL of the link would mostly be the same as for the AJAX request.
> Question to everyone: Would it make sense to only default the :href
> attribute to the value of :url if the link_to_remote handles a GET
> request but leave it at "#" for POST/PUT/DELETE since they're likely
> to be wrong anyways?

I like the spirit of that. I kinda wonder if it becomes a little too
magical. Some times the fallback URL will be set, some times it won't.
And if the implementor hasn't considered this and used a respond_to
block, expecting that all calls will be JS, then the non-JS user will
just end up seeing JS fragment code as his reply. Which seems to be
worse than a link not doing anything.

I think the safest thing in this case is simply to do nothing unless
the implementor has explicitly decided to allow for fallback
scenarios. And if he has, it'll be no problem for him to add the :url
parameter himself.

Most of my applications aren't designed to work with JS turned off
anyway. In fact, I bet that the majority of Ajax applications out
there are just the same. The effort to make it work in non-JS mode is
not worth the energy considering the tiny constituency for most
people. Thus we should make that scenario as smooth and logical as
possible while still allowing for someone to make a non-JS fallback
work if they put in a little extra effort.

> So how about the following idea:
> We should abstract the current functionality and create an
> AbstractJavaScriptGenerator that (maybe) provides common functionality
> sits in as a parent for PrototypeGenerator, JQueryGenerator,
> MooToolsGenerator, etc. In the config, we'd then have something like
> config.action_view.javascript_framework = :whatever that defaults
> to :prototype. Both, view helpers and RJS, should then use the methods
> of the respective generator.
> Moreover, we'd probably need to move each framework into its own
> subdirectory in /public/javascripts and then modify the
> javascript_include_tag :all to first load /public/
> javascripts/:framework and then (non-recursively) load all other files
> in the root.

I like that approach a lot. It definitely needs to be concrete,
though. So as we develop AbstractJavaScriptGenerator, we need to make
sure that it can span to be implemented as JQueryGenerator and
MooToolsGenerator or whatever. So a patch to core would be contingent
on the availability of at least 2 preferably 3 implementations of it.
I like config.action_view.javascript_generator as the option now that
we're going with *Generator as the class.

> How about making it configurable like my other suggestion? We could
> have something like config.action_view.use_unobtrusive_javascript =
> true that modifies *_to_remote in that it removes the onclick/onsubmit
> event and instead adds a default CSS class (e.g. "remote", but maybe
> also configurable) so we can easily add our unobtrusive JS layer to it
> (using lowpro or whatever).

If all the unobtrusive approach needs is a class, then why bother with
link_to_remote at all? Why not just use link_to and add the class?

Clemens

unread,
Jul 9, 2008, 4:14:04 PM7/9/08
to Ruby on Rails: Core
> I like the spirit of that. I kinda wonder if it becomes a little too
> magical. Some times the fallback URL will be set, some times it won't.
> And if the implementor hasn't considered this and used a respond_to
> block, expecting that all calls will be JS, then the non-JS user will
> just end up seeing JS fragment code as his reply. Which seems to be
> worse than a link not doing anything.
>
> I think the safest thing in this case is simply to do nothing unless
> the implementor has explicitly decided to allow for fallback
> scenarios. And if he has, it'll be no problem for him to add the :url
> parameter himself.

You've got a valid point. Not sure there, to be honest. Maybe some
other folks like to chime in and give their opinion on this subject? I
don't want to force the issue since it's not _that_ big of a deal but
I think it would be a step in the right direction.

> Most of my applications aren't designed to work with JS turned off
> anyway. In fact, I bet that the majority of Ajax applications out
> there are just the same. The effort to make it work in non-JS mode is
> not worth the energy considering the tiny constituency for most
> people. Thus we should make that scenario as smooth and logical as
> possible while still allowing for someone to make a non-JS fallback
> work if they put in a little extra effort.

Ha, this is _so_ true and I said pretty much the same to my client but
guess what - they couldn't care less! :-)
As long as we're talking about SaaS (where you can put it in the
"system requirements" on the signup page), admin areas of a page or a
page that ultimately has only a few users that you can influence.
that's a perfectly valid approach. But as soon as you can't really
control the user flow and the success of a page depends of _every_
user, you can't afford to lose a user just because they have JS
disabled. I'm experiencing this first hand right now, hence my strong
pro-unobtrusiveness attitude.

> I like that approach a lot. It definitely needs to be concrete,
> though. So as we develop AbstractJavaScriptGenerator, we need to make
> sure that it can span to be implemented as JQueryGenerator and
> MooToolsGenerator or whatever. So a patch to core would be contingent
> on the availability of at least 2 preferably 3 implementations of it.
> I like config.action_view.javascript_generator as the option now that
> we're going with *Generator as the class.

Definitely. It'd probably be a good idea to ask the JRails developers
to join in the effort since they already have some experience in this.
Plus, having at least two concrete implementations that implement the
abstract interface IMO proves that the interface is robust and will
probably only need a few tweaks here and there to also incorporate
other implementations.

Anyway, I've looked at the current implementation and I think this
would be pretty major change. I guess this needs a GitHub fork and at
least one person with a certain experience available in IRC or here at
the mailing list if questions regarding the current implementation
arise. Do you think that could be arranged?

> If all the unobtrusive approach needs is a class, then why bother with
> link_to_remote at all? Why not just use link_to and add the class?

Ouch, you got me there! ;-) At the moment I override link_to_remote
with this behavior as soon as I'm going unobtrusive (for a quick and
dirty interface, I usually prefer the obtrusive implementation). It
kinda hits the eye better like e.g. div_for(@post) instead of <div
id="<%= @post.id %>"> - that's why I prefer to name it link_to_remote
although it doesn't include the inline JS.

But you're probably right - it's not worth the fuzz. We should
probably be looking at the JSGenerator abstraction - I feel that this
is way more important and that quite a bunch of people would love JS-
agnostic Rails!

Zach Carter

unread,
Jul 9, 2008, 7:10:38 PM7/9/08
to Ruby on Rails: Core
It seems counter intuitive IMHO to feature RESTful resources yet have
delete as a link. The same way RESTful resources teach good design by
default, a proper delete would also.
Reply all
Reply to author
Forward
0 new messages