简体   繁体   中英

Rails controller update method only works for one call, then fails?

I have a simple url that will toggle one field in my search model. (locked) I want to toggle this field by clicking on a link.

example:

http://localhost:3000/search/toggle/fe5c72164908af20a7727f324e2fdbc1

The link works fine for one call then gives me the following error:

undefined method `locked' for nil:NilClass

the toggle path is just pointed to the searches update method:

route:

map.connect 'search/toggle/:id', :controller => 'searches', :action => 'update'

update action looks like:

  def update

   @search = Search.find_by_permalink(params[:id])

   if @search.locked == 1 then 
     @search.locked = 0 
   else 
     @search.locked = 1
    end 

    respond_to do |format|
      if @search.update_attributes(params[:search])
        flash[:notice] = 'Search was successfully updated.'
        format.xml  { head :ok }
        format.js
      else
        format.html { redirect_to('/users/current') }
        format.js
      end
    end
  end

I also have a ajax call looks like:

$j('a.lock-status').live('click', function(e) {
    $j.get($j(this).attr('href'));
    e.preventDefault();
});

To summarize:

If I enter a toggle URL into the URL bar of the browser it works once. If I hit refresh it fails and gives me the above error.

If I use the ajax call it works once.

If I use the ajax call then refresh the page, it will work for that first request every time.

I have a feeling this might have something to do with GET/POST requests in rails but I'm not sure? I have narrowed it down to:

@search = Search.find_by_permalink(params[:id])

retuning nill on any call after the first one, but I'm not sure why its doing that?

UPDATE 1:

Here is the log output for 2 requests. (1st works, 2nd fails):

Processing SearchesController#update (for 127.0.0.1 at 2011-06-13 16:19:39) [GET]
  Parameters: {"action"=>"update", "id"=>"9036304997196d83b20cba82a0cc67b8", "controller"=>"searches"}
  Search Columns (1.0ms)   SHOW FIELDS FROM `searches`
  Search Load (0.4ms)   SELECT * FROM `searches` WHERE (`searches`.`permalink` = '9036304997196d83b20cba82a0cc67b8') LIMIT 1
  SQL (0.1ms)   BEGIN
  Search Update (0.2ms)   UPDATE `searches` SET `locked` = 1, `updated_at` = '2011-06-13 23:19:39', `permalink` = '97894f26ba36761d04575260b132c230' WHERE `id` = 282
  SQL (0.3ms)   COMMIT
Rendering searches/update
Completed in 17ms (View: 6, DB: 2) | 200 OK [http://localhost/search/toggle/9036304997196d83b20cba82a0cc67b8]
  SQL (0.1ms)   SET NAMES 'utf8'
  SQL (0.1ms)   SET SQL_AUTO_IS_NULL=0


Processing SearchesController#update (for 127.0.0.1 at 2011-06-13 16:19:41) [GET]
  Parameters: {"action"=>"update", "id"=>"9036304997196d83b20cba82a0cc67b8", "controller"=>"searches"}
  Search Columns (1.0ms)   SHOW FIELDS FROM `searches`
  Search Load (0.4ms)   SELECT * FROM `searches` WHERE (`searches`.`permalink` = '9036304997196d83b20cba82a0cc67b8') LIMIT 1

NoMethodError (undefined method `locked' for nil:NilClass):
  app/controllers/searches_controller.rb:84:in `update'
  /Users/Nick/.rvm/rubies/ruby-1.8.7-p334/lib/ruby/1.8/webrick/httpserver.rb:104:in `service'
  /Users/Nick/.rvm/rubies/ruby-1.8.7-p334/lib/ruby/1.8/webrick/httpserver.rb:65:in `run'
  /Users/Nick/.rvm/rubies/ruby-1.8.7-p334/lib/ruby/1.8/webrick/server.rb:173:in `start_thread'
  /Users/Nick/.rvm/rubies/ruby-1.8.7-p334/lib/ruby/1.8/webrick/server.rb:162:in `start'
  /Users/Nick/.rvm/rubies/ruby-1.8.7-p334/lib/ruby/1.8/webrick/server.rb:162:in `start_thread'
  /Users/Nick/.rvm/rubies/ruby-1.8.7-p334/lib/ruby/1.8/webrick/server.rb:95:in `start'
  /Users/Nick/.rvm/rubies/ruby-1.8.7-p334/lib/ruby/1.8/webrick/server.rb:92:in `each'
  /Users/Nick/.rvm/rubies/ruby-1.8.7-p334/lib/ruby/1.8/webrick/server.rb:92:in `start'
  /Users/Nick/.rvm/rubies/ruby-1.8.7-p334/lib/ruby/1.8/webrick/server.rb:23:in `start'
  /Users/Nick/.rvm/rubies/ruby-1.8.7-p334/lib/ruby/1.8/webrick/server.rb:82:in `start'

Rendered rescues/_trace (109.8ms)
Rendered rescues/_request_and_response (1.1ms)
Rendering rescues/layout (internal_server_error)

UPDATE 2:

OK, I see what you guys are saying... not sure what would be changing the permalink. I'm going to double check the model code in the AM.

Thanks!

As nowk said, your permalink doesn't appear to be a constant ID for entries in your Search table.

On the first request you update the permalink value and in the second request you try to find the entry using the old permalink value, which clearly doesn't exist any more.

Your controller should check for nil after this line: @search = Search.find_by_permalink(params[:id]) If you got a nil you should return back with a 404, because the specified record was not found.

In this case, however, if a new permalink on every update makes sense for your application, on a successful toggle you might want to send back the updated permalink and use that for subsequent requests.

(Ideally this should have been a comment to nowk's answer, but I could not find the comment box. Hence another answer)

Try changing this:

if @search.update_attributes(params[:search])

to this:

if @search.save
Parameters: {"action"=>"update", "id"=>"9036304997196d83b20cba82a0cc67b8", "controller"=>"searches"}
  Search Columns (1.0ms)   SHOW FIELDS FROM `searches`
  Search Load (0.4ms)   SELECT * FROM `searches` WHERE (`searches`.`permalink` = '9036304997196d83b20cba82a0cc67b8') LIMIT 1
  Search Update (0.2ms)   UPDATE `searches` SET `locked` = 1, `updated_at` = '2011-06-13 23:19:39', `permalink` = '97894f26ba36761d04575260b132c230' WHERE `id` = 282

You sent in id 9036304997196d83b20cba82a0cc67b8 but your model is saving 97894f26ba36761d04575260b132c230

Why is your permalink being updated by a different value? Is your permalink setter regenerating on assignment?

If this is the case, would explain why you are getting nil back on the 2nd identical id request.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM