Forum: Ruby on Rails Creating new object using params posted from form

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Iain Rose (Guest)
on 2006-02-11 03:21
(Received via mailing list)
Hi,

I have a problem creating an new instance of an object using params
posted
from a form.

The object being created is not a sub class of ActiveRecord and is very
simple. It's model file is just:


class Search

  attr_accessor :major_build_id, :minor_build_id, :environment_id,
:system_id

end


The controller creates an empty instance variable the first time the
page is
called, else it tries to populate it with the values of params from the
form.


class ResultsController < ApplicationController

  def index
    list
    render :action => 'list'
  end

  def list
    if request.get?
      @search = Search.new
    else
      @search = Search.new(params[:search])
    end
  end

end


The form on the results/index page which populates the form posts back
to
itself and is also very simple

<%= start_form_tag %>

<div>Major Build Name<%= select :search, :major_build_id, [["Select",
""]]+@major_builds %></div>

<div>Minor Build Name<%= select :search, :minor_build_id, [["Select",
""]]+@minor_builds %></div>

<div>Environment<%= select :search, :environment_id, [["Select",
""]]+@environments %></div>

<div>System<%= select :search, :system_id, [["Select", ""]]+@systems
%></div>

<div><%= submit_tag 'Update Results' %></div>

<%= end_form_tag %>


The first time I call the page (using the GET request) is fine, but if I
use
the form to post any data I get an error.

ArgumentError in Results#index

wrong number of arguments (1 for 0)

RAILS_ROOT: ./script/../config/..
Application Trace <#> | Framework Trace <#> | Full Trace <#>

#{RAILS_ROOT}/app/controllers/results_controller.rb:13:in `initialize'
#{RAILS_ROOT}/app/controllers/results_controller.rb:13:in `new'
#{RAILS_ROOT}/app/controllers/results_controller.rb:13:in `list'
#{RAILS_ROOT}/app/controllers/results_controller.rb:4:in `index'
-e:3:in `load'
-e:3

c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.11.2/lib/action_controller/base.rb:853:in
`send'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.11.2/lib/action_controller/base.rb:853:in
`perform_action_without_filters'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.11.2/lib/action_controller/filters.rb:332:in
`perform_action_without_benchmark'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.11.2/lib/action_controller/benchmarking.rb:69:in
`perform_action_without_rescue'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.11.2/lib/action_controller/benchmarking.rb:69:in
`measure'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.11.2/lib/action_controller/benchmarking.rb:69:in
`perform_action_without_rescue'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.11.2/lib/action_controller/rescue.rb:82:in
`perform_action'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.11.2/lib/action_controller/base.rb:369:in
`send'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.11.2/lib/action_controller/base.rb:369:in
`process_without_session_management_support'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.11.2/lib/action_controller/session_management.rb:116:in
`process'
c:/ruby/lib/ruby/gems/1.8/gems/rails-1.0.0/lib/dispatcher.rb:38:in
`dispatch'
c:/ruby/lib/ruby/gems/1.8/gems/rails-1.0.0/lib/webrick_server.rb:117:in
`handle_dispatch'
c:/ruby/lib/ruby/gems/1.8/gems/rails-1.0.0/lib/webrick_server.rb:83:in
`service'
c:/ruby/lib/ruby/1.8/webrick/httpserver.rb:104:in `service'
c:/ruby/lib/ruby/1.8/webrick/httpserver.rb:65:in `run'
c:/ruby/lib/ruby/1.8/webrick/server.rb:155:in `start_thread'
c:/ruby/lib/ruby/1.8/webrick/server.rb:144:in `start'
c:/ruby/lib/ruby/1.8/webrick/server.rb:144:in `start_thread'
c:/ruby/lib/ruby/1.8/webrick/server.rb:94:in `start'
c:/ruby/lib/ruby/1.8/webrick/server.rb:89:in `each'
c:/ruby/lib/ruby/1.8/webrick/server.rb:89:in `start'
c:/ruby/lib/ruby/1.8/webrick/server.rb:79:in `start'
c:/ruby/lib/ruby/1.8/webrick/server.rb:79:in `start'
c:/ruby/lib/ruby/gems/1.8/gems/rails-1.0.0/lib/webrick_server.rb:69:in
`dispatch'
c:/ruby/lib/ruby/gems/1.8/gems/rails-1.0.0/lib/commands/servers/webrick.rb:59
c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:18:in
`require__'
c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:18:in
`require'
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-1.2.5/lib/active_support/dependencies.rb:214:in
`require'
c:/ruby/lib/ruby/gems/1.8/gems/rails-1.0.0/lib/commands/server.rb:28
c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:18:in
`require__'
c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:18:in
`require'
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-1.2.5/lib/active_support/dependencies.rb:214:in
`require'
./script/server:3

#{RAILS_ROOT}/app/controllers/results_controller.rb:13:in `initialize'
#{RAILS_ROOT}/app/controllers/results_controller.rb:13:in `new'
#{RAILS_ROOT}/app/controllers/results_controller.rb:13:in `list'
#{RAILS_ROOT}/app/controllers/results_controller.rb:4:in `index'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.11.2/lib/action_controller/base.rb:853:in
`send'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.11.2/lib/action_controller/base.rb:853:in
`perform_action_without_filters'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.11.2/lib/action_controller/filters.rb:332:in
`perform_action_without_benchmark'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.11.2/lib/action_controller/benchmarking.rb:69:in
`perform_action_without_rescue'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.11.2/lib/action_controller/benchmarking.rb:69:in
`measure'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.11.2/lib/action_controller/benchmarking.rb:69:in
`perform_action_without_rescue'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.11.2/lib/action_controller/rescue.rb:82:in
`perform_action'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.11.2/lib/action_controller/base.rb:369:in
`send'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.11.2/lib/action_controller/base.rb:369:in
`process_without_session_management_support'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.11.2/lib/action_controller/session_management.rb:116:in
`process'
c:/ruby/lib/ruby/gems/1.8/gems/rails-1.0.0/lib/dispatcher.rb:38:in
`dispatch'
c:/ruby/lib/ruby/gems/1.8/gems/rails-1.0.0/lib/webrick_server.rb:117:in
`handle_dispatch'
c:/ruby/lib/ruby/gems/1.8/gems/rails-1.0.0/lib/webrick_server.rb:83:in
`service'
c:/ruby/lib/ruby/1.8/webrick/httpserver.rb:104:in `service'
c:/ruby/lib/ruby/1.8/webrick/httpserver.rb:65:in `run'
c:/ruby/lib/ruby/1.8/webrick/server.rb:155:in `start_thread'
c:/ruby/lib/ruby/1.8/webrick/server.rb:144:in `start'
c:/ruby/lib/ruby/1.8/webrick/server.rb:144:in `start_thread'
c:/ruby/lib/ruby/1.8/webrick/server.rb:94:in `start'
c:/ruby/lib/ruby/1.8/webrick/server.rb:89:in `each'
c:/ruby/lib/ruby/1.8/webrick/server.rb:89:in `start'
c:/ruby/lib/ruby/1.8/webrick/server.rb:79:in `start'
c:/ruby/lib/ruby/1.8/webrick/server.rb:79:in `start'
c:/ruby/lib/ruby/gems/1.8/gems/rails-1.0.0/lib/webrick_server.rb:69:in
`dispatch'
c:/ruby/lib/ruby/gems/1.8/gems/rails-1.0.0/lib/commands/servers/webrick.rb:59
c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:18:in
`require__'
c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:18:in
`require'
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-1.2.5/lib/active_support/dependencies.rb:214:in
`require'
c:/ruby/lib/ruby/gems/1.8/gems/rails-1.0.0/lib/commands/server.rb:28
c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:18:in
`require__'
c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:18:in
`require'
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-1.2.5/lib/active_support/dependencies.rb:214:in
`require'
./script/server:3
-e:3:in `load'
-e:3

Request

*Parameters*: {"search"=>{"minor_build_id"=>"", "major_build_id"=>"",
"system_id"=>"1", "environment_id"=>""}, "commit"=>"Update Results"}

However I've found that if I update the "list" action in the results
controller to this longer and uglier version, it works.

  def list
    @search = Search.new
    if request.post?
      @search.major_build_id = params[:search]["major_build_id"].to_i()
      @search.minor_build_id = params[:search]["minor_build_id"].to_i()
      @search.environment_id = params[:search]["environment_id"].to_i()
      @search.system_id = params[:search]["system_id"].to_i()
    end
end

This seems a bit long winded and I'm sure there is a simpler and more
elegant way. Is there something I'm missing?

thanks

Iain
unknown (Guest)
on 2006-02-11 03:46
(Received via mailing list)
Hi --

On Fri, 10 Feb 2006, Iain Rose wrote:

>
>
>    else
>      @search = Search.new(params[:search])

What you've done is equivalent to:

   class C
   end

   c = C.new("arg")  # wrong # of arguments: 1 for 0

You'd need to write an initialize method -- for example

   class C
     def initialize(*x)   # optional argument x
       # do whatever here
     end
   end

Similarly, in your Search class, you would need to define initialize,
probably to handle an optional argument (since it looks like you want
to be able to call it with or without).

>      @search.minor_build_id = params[:search]["minor_build_id"].to_i()
>      @search.environment_id = params[:search]["environment_id"].to_i()
>      @search.system_id = params[:search]["system_id"].to_i()
>    end
> end
>
> This seems a bit long winded and I'm sure there is a simpler and more
> elegant way. Is there something I'm missing?

If you do something like this in the Search class:

   class Search
     attr_accessor :major_build_id, :minor_build_id,
                   :environment_id, :system_id

     def initialize(*search_hash)
       if search_hash
         search_hash.each do |key,value|
           send("#{key}=", value)  # This calls the appropriate
                                   # writer method, matching the key
         end
       end
     end
   end

then you could do:

   @search = Search.new(params[:search])

and/or

   @search = Search.new

in the controller, depending on conditions, etc.

(It seems a bit anomalous to have this Search class among the models,
but that's another matter :-)


David

--
David A. Black (removed_email_address@domain.invalid)
Ruby Power and Light (http://www.rubypowerandlight.com)

"Ruby for Rails" chapters now available
from Manning Early Access Program! http://www.manning.com/books/black
Iain Rose (Guest)
on 2006-02-11 07:31
(Received via mailing list)
Thanks for the advice.

Can I ask why you don't need to do this when using models that exist in
the
db. For example, when I use the scaffold generator to create a model
called
Search in a controller called Results, I get this in the controller ....

class ResultsController < ApplicationController
...............
  def create
    @search = Search.new(params[:search])
    if @search.save
      flash[:notice] = 'Search was successfully created.'
      redirect_to :action => 'list'
    else
      render :action => 'new'
    end
  end

I'm not intending to use scaffolding throughout my app but it proves it
can
work out of the box (sometimes). The class definition of the Search
model
doesn't have an initialize method. Does it just inherit something
simliar to
your suggestion from it's super class?

Also, as this is my first attempt at a Rails app (I'm branching out on
my
own after working through the agile book), can you explain what you mean
by
...

It seems a bit anomalous to have this Search class among the models

I'd like to start on the right tracks and not get into bad habits.

Thanks again for the advice.

Iain
Pete Y. (Guest)
on 2006-02-11 23:32
(Received via mailing list)
David is right. The scaffolding code is like that because it expects
Search to be an ActiveRecord subclass. It's ActiveRecord that
provides the ability to call new with a hash. If you're not
subclassing ActiveRecord, you need to implement that yourself.

Cheers,

Pete Y.
This topic is locked and can not be replied to.