开发者

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

开发者 https://www.devze.com 2023-03-12 10:35 出处:网络
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.

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 p开发者_Go百科ath 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)


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.


Try changing this:

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

to this:

if @search.save
0

精彩评论

暂无评论...
验证码 换一张
取 消