Simply Helpful - Is it being used?

There is a reference in "Agile Web Development with Rails", 2nd
edition (footnote on page 483) to the effect that "Simply Helpful",
which is to facilitate integration of models, REST and form_for, will
likely end up in core Rails.
However, I have seen woefully little reaction to it and I was
wondering if it is worth using in my new application.
Any advice would be warmly appreciated.
Thanks

Yes, use it. I don't see any drawback. In recent versions there is a new
way to create URLs for objects that is very helpful if you're
generically working with resources, namely polymorphic_url(@object).

Michael

> However, I have seen woefully little reaction to it and I was
> wondering if it is worth using in my new application.

I use it on every project now, it really feels like part of Rails.
The url helpers, and methods like dom_id and dom_class DRY up your
views a lot and make AJAX effects simpler to employ, as you get a set
of conventions for referencing DOM elements.

-Patrick Ewing

Thanks very much

Is there a tutorial?

It doesn't handle nested resources :frowning:

Here is my experience with it: I developed on application with Rails 1.2.2 without Simply_Helper plugin. I wrote lot of tests and once my application was ready to be released I refactored my code to use Simply Helpful plugin. All my tests passed (unit, functional, integration and Selenium) and I was confident that what I was doing was working.

Suddenly for some reason when I installed some plugin the tests began to fail due to Simply Helpful. I removed the simply helpful tags and everything now works fine. I still have not found out what went wrong with the Simply Helpful when other plugins are installed.

Hi --

There is a reference in "Agile Web Development with Rails", 2nd
edition (footnote on page 483) to the effect that "Simply Helpful",
which is to facilitate integration of models, REST and form_for, will
likely end up in core Rails.
However, I have seen woefully little reaction to it and I was
wondering if it is worth using in my new application.

I think it is indeed used quite widely. I have a bit of a stumbling
block with the form helper stuff, because I strongly dislike this
idiom:

  def new
     @user = User.new
  end

where you create an AR instance and then discard it, for the sole
purpose of querying it as to whether or not it's a new object.[1] But
don't listen to me; I'm in the minority on this :slight_smile: And the general
idea of integrating stuff and making it less repetitive I think is
very sound, of course.

David

[1] http://dablog.rubypal.com/2006/12/23/more-a-than-r-reconsidering-the-new-ar-object

I wondered why new had that line of code. I commented out the line that creates an empty object in the new method. Still all my tests pass and everything seems fine. So what would the test look like for new method that creates the object that is discarded?

I'm not sure why you dislike it. The solution you propose in the blog
entry (User.proto) is essentially what User.new provides: a
prototypical, blank-slate user.

There's nothing overkill about this. A new User is no more or less
than what's needed to show a new user.

I think that whether you use a singleton or a new instance per request
should be a question of implementation rather than idiom.

Best,
jeremy

Hi --

> I think it is indeed used quite widely. I have a bit of a stumbling
> block with the form helper stuff, because I strongly dislike this
> idiom:
>
> def new
> @user = User.new
> end
>
> where you create an AR instance and then discard it, for the sole
> purpose of querying it as to whether or not it's a new object.[1] But
> don't listen to me; I'm in the minority on this :slight_smile: And the general
> idea of integrating stuff and making it less repetitive I think is
> very sound, of course.

I'm not sure why you dislike it. The solution you propose in the blog
entry (User.proto) is essentially what User.new provides: a
prototypical, blank-slate user.

There's nothing overkill about this. A new User is no more or less
than what's needed to show a new user.

I think that whether you use a singleton or a new instance per request
should be a question of implementation rather than idiom.

Maybe. I don't have a slam-dunk technical argument against it; it
just strikes me as kind of loose, in the sense that, although
AR::B.new does not create a database record, the whole apparatus
exists as a way to persist instances to a database, so deciding up
front to create an instance that has zero chance of being persisted
seems to me contrary to the semantic thrust of the system.

As I said, I'm in the minority :slight_smile: I understand the reasoning behind
it, and I imagine I'll get used to seeing it, but it doesn't sit well
with me. I'd actually say it's more an idiom thing than an
implementation thing: even if proto (or some other better name) were
an alias of new, it would be more expressive of the status of this
particular instance as a kind of dead-end/stand-in object of
reference.

David

David, I tend to agree - it strikes me my disturbance lies in the tightly coupling of the 'Model to AR.

If rails models were independent of storage, then Model.new would sit better with me.

Given the above, it is not implementation - but a symptom of the current Model implementation as ActiveRecord. I'll bet dollars to donuts that we'll see a separation down the road.

The Model as means storage rears it's head in my tests as well - I want to test my Models - not AR; and mocking AR is not a solution that sits right with me.

cheers,
Jodi

Maybe. I don't have a slam-dunk technical argument against it; it
just strikes me as kind of loose, in the sense that, although
AR::B.new does not create a database record, the whole apparatus
exists as a way to persist instances to a database, so deciding up
front to create an instance that has zero chance of being persisted
seems to me contrary to the semantic thrust of the system.

Ah, but it does. The create action has the corresponding
  user.attributes = params[:user]
  user.save

So imagine we're Seaside: the new and create actions just happen to be
punctuated by a request+response:
  GET /users/new user = User.new
  POST /users user.update_attributes params[:user]

Regarding User's narrow persistence destiny, I heartily disagree! User
models a real entity in the problem domain-- its characteristics and
behavior-- and Active Record is used to persist it, not the other way
around.

As I said, I'm in the minority :slight_smile: I understand the reasoning behind
it, and I imagine I'll get used to seeing it, but it doesn't sit well
with me. I'd actually say it's more an idiom thing than an
implementation thing: even if proto (or some other better name) were
an alias of new, it would be more expressive of the status of this
particular instance as a kind of dead-end/stand-in object of
reference.

I hope I've persuaded you :wink: Seen in another light, there is no dead
end or special status for this instance.

Best,
jeremy

Hi --

> Maybe. I don't have a slam-dunk technical argument against it; it
> just strikes me as kind of loose, in the sense that, although
> AR::B.new does not create a database record, the whole apparatus
> exists as a way to persist instances to a database, so deciding up
> front to create an instance that has zero chance of being persisted
> seems to me contrary to the semantic thrust of the system.

Ah, but it does. The create action has the corresponding
  user.attributes = params[:user]
  user.save

But that user isn't the same instance as the @user from the new
action. Somewhere in create you instantiate User again.

So imagine we're Seaside: the new and create actions just happen to be
punctuated by a request+response:
  GET /users/new user = User.new
  POST /users user.update_attributes params[:user]

OK... but we're not :slight_smile: The separation, and the need to instantiate
the class twice, are very palpable to me in the Rails scenario. If
the semantics were as above, then the situation might be different;
but it's hard to project that into the current semantics.

In fact, that might be exactly what bothers me about it. The idea is
that you have a new instance, and someone fills out some fields for
it, and you save it -- but that idea is very much *not* manifested in
the actual code.

Take, by way of comparison and contrast, the instance variable sharing
between controller and view. That's a case where the sameness of the
objects (@var and @var) is a deception -- but it's you, the
programmer, who are deceived, so that you have a seamless virtual
scope for instance variables even though 'self' has changed.

In the User.new case, I think the problem is that it sort of wants to
be like that, but there's no deception: you actually have to program
the two instances and you can see graphically in your code that they
have no relation to each other.

Regarding User's narrow persistence destiny, I heartily disagree! User
models a real entity in the problem domain-- its characteristics and
behavior-- and Active Record is used to persist it, not the other way
around.

It's sort of both, though, in the sense that the object is not a
completely database-innocent (so to speak) object which happens to be
sent along to an AR subsystem to be persisted. It's already bitten the
database apple; it encapsulates knowledge of the database, and knows
how to persist itself.

I do know what you mean, though, and I've tried to view it that way.
It doesn't totally work for me; it still feels like pressing an AR
object into service outside of its sweet spot.

> As I said, I'm in the minority :slight_smile: I understand the reasoning behind
> it, and I imagine I'll get used to seeing it, but it doesn't sit well
> with me. I'd actually say it's more an idiom thing than an
> implementation thing: even if proto (or some other better name) were
> an alias of new, it would be more expressive of the status of this
> particular instance as a kind of dead-end/stand-in object of
> reference.

I hope I've persuaded you :wink: Seen in another light, there is no dead
end or special status for this instance.

I'm afraid I'm still a disbeliever :slight_smile: But that's OK -- not everyone
has to like every idiom, and it's very interesting to talk and think
about this particular one, I find.

David

David, I tend to agree - it strikes me my disturbance lies in the
tightly coupling of the 'Model to AR.

If rails models were independent of storage, then Model.new would sit
better with me.

I think Active Record succeeds because of this dependence.

Why beat around the bush when you're almost always working with a
SQL-speaking relational database?

By assuming that object instance <-> table row, that attributes of
instances <-> fields of that row, and that associations among
instances <-> foreign-key relations among tables, we're able to shrug
off the heavy burden of arbitrariness in favor a simple, elegant
correspondence whose power is derived from its *avoidance* of a
generic, indirect mapping. Delightful!

By no means does this rule out loading your AR classes with behavior
modeling your domain. On the contrary, I've admired many an app whose
domain is richly expressed by its AR classes.

Given the above, it is not implementation - but a symptom of the
current Model implementation as ActiveRecord. I'll bet dollars to
donuts that we'll see a separation down the road.

I encourage you to reexamine your odds-making :wink:

The Model as means storage rears it's head in my tests as well - I
want to test my Models - not AR; and mocking AR is not a solution
that sits right with me.

Whether you subclass AR::Base or include SomePersistenceStrategy,
you're going to have to stub it out for tests one way or another. I've
been very happy with Mocha for quick, natural mocks and stubs.

Best,
jeremy

Hi --

>
> > Maybe. I don't have a slam-dunk technical argument against it; it
> > just strikes me as kind of loose, in the sense that, although
> > AR::B.new does not create a database record, the whole apparatus
> > exists as a way to persist instances to a database, so deciding up
> > front to create an instance that has zero chance of being persisted
> > seems to me contrary to the semantic thrust of the system.
>
> Ah, but it does. The create action has the corresponding
> user.attributes = params[:user]
> user.save

But that user isn't the same instance as the @user from the new
action. Somewhere in create you instantiate User again.

I see what you're saying, but don't understand why the User.new used
to build the edit form being the identical instance to the one saved
is important.

Their equivalence is enough for me. Perhaps it helps to think of a new
instance as a value object (equality by attributes) rather than an
entity (equality by id.)

> So imagine we're Seaside: the new and create actions just happen to be
> punctuated by a request+response:
> GET /users/new user = User.new
> POST /users user.update_attributes params[:user]

OK... but we're not :slight_smile: The separation, and the need to instantiate
the class twice, are very palpable to me in the Rails scenario. If
the semantics were as above, then the situation might be different;
but it's hard to project that into the current semantics.

I think they *are* as above :wink:

In fact, that might be exactly what bothers me about it. The idea is
that you have a new instance, and someone fills out some fields for
it, and you save it -- but that idea is very much *not* manifested in
the actual code.

Take, by way of comparison and contrast, the instance variable sharing
between controller and view. That's a case where the sameness of the
objects (@var and @var) is a deception -- but it's you, the
programmer, who are deceived, so that you have a seamless virtual
scope for instance variables even though 'self' has changed.

In the User.new case, I think the problem is that it sort of wants to
be like that, but there's no deception: you actually have to program
the two instances and you can see graphically in your code that they
have no relation to each other.

How would it feel to marshal the instance between requests?

GET /users/new session[:user] = User.new
POST /users session[:user].update_attributes params[:user]

Then the code can be collapsed to a sensible linear flow with the
intervening request as params[:user] = $interweb.gets

> Regarding User's narrow persistence destiny, I heartily disagree! User
> models a real entity in the problem domain-- its characteristics and
> behavior-- and Active Record is used to persist it, not the other way
> around.

It's sort of both, though, in the sense that the object is not a
completely database-innocent (so to speak) object which happens to be
sent along to an AR subsystem to be persisted. It's already bitten the
database apple; it encapsulates knowledge of the database, and knows
how to persist itself.

I do know what you mean, though, and I've tried to view it that way.
It doesn't totally work for me; it still feels like pressing an AR
object into service outside of its sweet spot.

But it's not going to hell for that sweet bite of knowledge! It's
free to live a happy object life despite driving a database to work.

Too many metaphors, I know :wink:

> > As I said, I'm in the minority :slight_smile: I understand the reasoning behind
> > it, and I imagine I'll get used to seeing it, but it doesn't sit well
> > with me. I'd actually say it's more an idiom thing than an
> > implementation thing: even if proto (or some other better name) were
> > an alias of new, it would be more expressive of the status of this
> > particular instance as a kind of dead-end/stand-in object of
> > reference.
>
> I hope I've persuaded you :wink: Seen in another light, there is no dead
> end or special status for this instance.

I'm afraid I'm still a disbeliever :slight_smile: But that's OK -- not everyone
has to like every idiom, and it's very interesting to talk and think
about this particular one, I find.

Agreed!

Best,
jeremy

Resolved the simply helpful problem, if I have the line: @user = User.create in the new method, I am able to use simply helpful plugin without any problems.

Hi --

David,

...ahem, I am assuming here that you have an 'edit' and a 'new' view
and thus...

<% form_for Person %> /* new.rhtml */
<% form_for @person %> /* in edit.rhtml */

If that is not the case in your apps, as it usally is in mine, then
ignore my suggestion; it would be of no help in your quest for a more
'likeable idiom'

-christos