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