Yes thank you, I read Yehuda's articles before but was not thinking
of :new_record? when I was working with my Session class. So I had to
learn it the hard way.

On Feb 21, 2:07 pm, Conrad Taylor <[email protected]> wrote:
> On Sun, Feb 21, 2010 at 6:11 AM, Daniel Guettler
> <[email protected]>wrote:
>
>
>
>
>
> > Initially looking at the problem suggested a routing bug since as
> > stated in my first message the output in the log file contained:
>
> >  Started POST "/login" for 127.0.0.1
>
> > even so submitting the login form actually used _method => :put which
> > in Rails 2.x would have been reported as:
>
> >  Processing ... (for 127.0.0.1) [PUT]
>
> > further investigation (after my first post) made clear that the
> > problem was not related to routing but was due to the way form_for
> > determines which method to use if not specified.
> > Since I was NOT using ActiveRecord::Base my Session was NOT responding
> > to :new_record? which caused form_for adding _method => :put
>
> > Now what is the takeaway message here?
> > 1) Session should implement a form of new_record? if you want to use
> > it with form_for OR
> > 2) explicitly set the :html => { :method => :post } in form_for so it
> > doesn't make wrong guesses
> > 3) it may be worth considering changing the logging to actually read:
> > Started PUT "/login" for 127.0.0.1 IFF the _method parameter is set
> > to :put
>
> In short, you're trying to make non ArctiveRecord objects behave like
> ActiveRecord.  Thus, I would recommend reading the very good write-up
> by Yehuda Katz, a Rails core member, because your object,  as it stands,
> isn't fully compatible with Rails 3, more specifically, ActionPack:
>
> http://yehudakatz.com/2010/01/10/activemodel-make-any-ruby-object-fee...
>
> Good luck,
>
> -Conrad
>
>
>
>
>
> > On Feb 21, 5:01 am, Conrad Taylor <[email protected]> wrote:
> > > On Sat, Feb 20, 2010 at 9:14 PM, Daniel Guettler
> > > <[email protected]>wrote:
>
> > > > What are you trying to prove here?
> > > > I'm not using ActiveRecord and my Session class IS NOT inheriting from
> > > > ActiveRecord::Base either
>
> > > I'm trying to prove to you that ActiveModel works without
> > > ActiveRecord::Base.  It
> > > works so much so I'm building ActiveRecord style interface to work with
> > > Maglev.
> > > Next, in your initial e-mail to the mailing list, you mentioned that
> > there
> > > was a possible
> > > bug in Rails 3 routing.  What does this have to do with the possible bug
> > in
> > > routing?
>
> > > -Conrad
>
> > > > Session.anchestors => [Session, ActiveModel::Validations,
> > > > ActiveSupport::Callbacks, Object, PP::ObjectMixin,
> > > > JSON::Ext::Generator::GeneratorMethods::Object,
> > > > ActiveSupport::Dependencies::Loadable, Arel::Sql::ObjectExtensions,
> > > > Arel::ObjectExtensions, Kernel, BasicObject]
>
> > > > I know how to add validations to it etc. (not included in this post to
> > > > keep the examples lean) the point I'm trying to make here is the
> > > > dependency of form_for on the :new_record? method.
>
> > > > On Feb 20, 10:04 pm, Conrad Taylor <[email protected]> wrote:
> > > > > On Sat, Feb 20, 2010 at 6:56 PM, Conrad Taylor <[email protected]>
> > > > wrote:
> > > > > > On Sat, Feb 20, 2010 at 5:19 PM, Daniel Guettler <
> > > > > > [email protected]> wrote:
>
> > > > > >> Ok but I'm not using an ActiveRecord instance here. I just
> > temporarily
> > > > > >> made Session inherit from ActiveRecord::Base for testing purpose.
> > And
> > > > > >> the attr_accessors didn't override anything since the table I
> > created
> > > > > >> only contained an id attribute.
>
> > > > > > Session class inherits from ActiveRecord::Base.  Thus, if you
> > create an
> > > > > > instance(s) of
> > > > > > Session, then each instance is a type of ActiveRecord::Base.
>
> > > > > >> The idea here was to just create a normal class (not inheriting
> > from
> > > > > >> ActiveRecord) and to only use the validations module. The session
> > is
> > > > > >> not going to be stored in the database.
>
> > > > > > Then you can simply do the following:
>
> > > > > > *require 'active_model'
>
> > > > > > class Session
> > > > > >   include ActiveModel::Validations
>
> > > > > >   validates_presence_of :login
> > > > > >   validates_presence_of :password
>
> > > > > >   attr_accessor :login, :password
>
> > > > > >   def initialize( attributes = {})
> > > > > >     @attributes = attributes
> > > > > >   end
>
> > > > > > end
>
> > > > > > puts "valid session"
> > > > > > puts
>
> > > > > > session = Session.new( :login => "foo", :password => "bar" )
> > > > > > puts session.valid? # => false
> > > > > > puts session.password = "foobar"
> > > > > > puts session.valid? # => true
> > > > > > puts session.errors
>
> > > > > > puts
>
> > > > > > puts "invalid session"
> > > > > > puts
> > > > > > session2 = Session.new( :login => "", :password => "bar" )
> > > > > > puts session2.valid? # => false
> > > > > > puts session2.password = "foobar"
> > > > > > puts session2.valid? # => true
> > > > > > puts session2*
>
> > > > > > *
> > > > > > *
> > > > > > Good luck,
>
> > > > > > -Conrad
>
> > > > > Here's a better version:
>
> > > > > require 'active_model'
>
> > > > > class Session
>
> > > > >   include ActiveModel::Validations
>
> > > > >   validates_presence_of :login
> > > > >   validates_presence_of :password
>
> > > > >   attr_accessor :login, :password
>
> > > > >   def initialize( attributes = {})
> > > > >     @attributes = attributes
> > > > >   end
>
> > > > > end
>
> > > > > puts "valid session"
> > > > > puts
>
> > > > > session = Session.new
> > > > > puts session.login = 'foo'
> > > > > puts session.password = 'bar'
> > > > > puts session.valid? # => true
> > > > > puts session.errors
>
> > > > > puts
>
> > > > > puts "invalid session"
> > > > > puts
> > > > > session2 = Session.new
> > > > > puts session2.password = "bar"
> > > > > puts session2.valid? # => true
> > > > > puts session2.errors
>
> > > > > I wish that this helps.
>
> > > > > Good luck,
>
> > > > > -Conrad
>
> > > > > >> The original implementation of Session was:
>
> > > > > >> class Session
> > > > > >>   include ActiveModel::Validations
> > > > > >>  attr_accessor :login, :password, :id
> > > > > >> end
>
> > > > > >> On Feb 20, 7:53 pm, Conrad Taylor <[email protected]> wrote:
> > > > > >> > On Sat, Feb 20, 2010 at 4:49 PM, Conrad Taylor <
> > [email protected]>
> > > > > >> wrote:
> > > > > >> > > On Sat, Feb 20, 2010 at 4:38 PM, Daniel Guettler <
> > > > > >> > > [email protected]> wrote:
>
> > > > > >> > >> Yes, this is correct and expected, the question to me is
> > rather
> > > > if it
> > > > > >> > >> is expected behavior to assume an update operation if the
> > object
> > > > > >> > >> doesn't respond to :new_record?
>
> > > > > >> > > Yes, this is expected because AR instance is either new (i.e.
> > > > hasn't
> > > > > >> been
> > > > > >> > > saved) or
> > > > > >> > > not new (i.e. has been saved).  One can easily test this in
> > the
> > > > Rails
> > > > > >> > > console.
>
> > > > > >> > > -Conrad
>
> > > > > >> > irb(main):026:0> post = Post.new
> > > > > >> > => #<Post id: nil, title: nil, body: nil, created_at: nil,
> > > > updated_at:
> > > > > >> nil>
> > > > > >> > irb(main):027:0> post.new_record?
> > > > > >> > => true
> > > > > >> > irb(main):028:0> post.save
> > > > > >> > => true
> > > > > >> > irb(main):029:0> post.new_record?
> > > > > >> > => false
>
> > > > > >> > -Conrad
>
> > > > > >> > > On Feb 20, 7:34 pm, Conrad Taylor <[email protected]> wrote:
> > > > > >> > >> > On Sat, Feb 20, 2010 at 4:32 PM, Daniel Guettler
> > > > > >> > >> > <[email protected]>wrote:
>
> > > > > >> > >> > > So to solve this, the reason why this ends up using
> > :method
> > > > =>
> > > > > >> :put is
> > > > > >> > >> > > the following code in "apply_form_for_options!":
>
> > > > > >> > >> > >        html_options =
> > > > > >> > >> > >          if object.respond_to?(:new_record?) &&
> > > > > >> object.new_record?
> > > > > >> > >> > >            { :class  => dom_class(object, :new),  :id =>
> > > > > >> > >> > > dom_id(object), :method => :post }
> > > > > >> > >> > >          else
> > > > > >> > >> > >            { :class  => dom_class(object, :edit), :id =>
> > > > > >> > >> > > dom_id(object, :edit), :method => :put }
> > > > > >> > >> > >          end
>
> > > > > >> > >> > Yes, this is basic Rails.  PUT HTTP verb translates to an
> > > > update
> > > > > >> action.
>
> > > > > >> > >> > -Conrad
>
> > > > > >> > >> > > which means for every object not responding to
> > new_record? it
> > > > > >> will
> > > > > >> > >> > > automatically set the method to PUT
> > > > > >> > >> > > since the options are reverse merged later with the
> > provided
> > > > > >> options
> > > > > >> > >> > > this can be avoided by setting explicit :html => {
> > :method =>
> > > > > >> :post }
> > > > > >> > >> > > in form_for - not sure though if this is entended
> > behavior...
>
> > > > > >> > >> > > If someone has some inside view comments would be
> > > > appreciated...
>
> > > > > >> > >> > > On Feb 20, 7:24 pm, Daniel Guettler <
> > > > [email protected]>
> > > > > >> > >> wrote:
> > > > > >> > >> > > > Ok what is really happening here is that
> > > > for_for(Session.new,
> > > > > >> :url
> > > > > >> > >> =>
> > > > > >> > >> > > > login_path) includes a hidden input field setting
> > _method
> > > > to
> > > > > >> put
> > > > > >> > >> which
> > > > > >> > >> > > > correctly complains about a routing error since no
> > route is
> > > > > >> defined
> > > > > >> > >> > > > for PUT /login
> > > > > >> > >> > > > Remaining question to me is why does form_for set the
> > > > method to
> > > > > >> PUT
>
> > > > > >> > >> > > > Session.new.new_record? => NoMethodError
> > > > > >> > >> > > > Session.new.id => nil
>
> > > > > >> > >> > > > On Feb 20, 7:17 pm, Daniel Guettler <
> > > > [email protected]
>
> > > > > >> > >> wrote:
>
> > > > > >> > >> > > > > ah the last bit of the previous message should have
> > not
> > > > been
> > > > > >> in
> > > > > >> > >> there,
> > > > > >> > >> > > > > but should have been in this message.
>
> > > > > >> > >> > > > > Changing the Session class to:
>
> > > > > >> > >> > > > > class Session < ActiveRecord::Base
> > > > > >> > >> > > > > end
>
> > > > > >> > >> > > > > and adding a table to the database (which is not the
> > goal
> > > > > >> here
> > > > > >> > >> just a
> > > > > >> > >> > > > > workaround for figuring out what's going on
>
> ...
>
> read more »

-- 
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Talk" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/rubyonrails-talk?hl=en.

Reply via email to