Rails控制器更新方法仅适用于一个调用,然后失败?

时间:2011-06-13 23:11:34

标签: ruby-on-rails

我有一个简单的网址,可以在我的搜索模型中切换一个字段。 (已锁定)我想通过点击链接切换此字段。

示例:

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

该链接适用于一个呼叫然后给我以下错误:

undefined method `locked' for nil:NilClass

切换路径只是指向搜索更新方法:

路线:

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

更新操作如下:

  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

我也有一个ajax调用看起来像:

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

总结:

如果我在浏览器的网址栏中输入切换网址,则可以使用一次。如果我点击刷新它失败并给我上述错误。

如果我使用ajax调用它可以运行一次。

如果我使用ajax调用然后刷新页面,它将每次都适用于第一个请求。

我觉得这可能与rails中的GET / POST请求有关,但我不确定?我把它缩小到:

@search = Search.find_by_permalink(params[:id])
在第一次调用后的任何调用中重新调整nill,但我不确定为什么会这样做?

更新1:

以下是2个请求的日志输出。 (第1次作品,第2次失败):

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)

更新2:

好的,我看到你们在说什么......不确定是什么会改变固定链接。我要仔细检查AM中的型号代码。

谢谢!

3 个答案:

答案 0 :(得分:1)

正如nowk所说,您的固定链接似乎不是搜索表中条目的常量ID。

在第一个请求中更新永久链接值,在第二个请求中,您尝试使用旧的永久链接值查找条目,这显然不再存在。

您的控制器应在此行之后检查nil:@search = Search.find_by_permalink(params[:id])如果您没有,则应返回404,因为找不到指定的记录。

但是,在这种情况下,如果每次更新的新永久链接对您的应用程序有意义,那么在成功切换时您可能希望发回更新的永久链接并将其用于后续请求。

(理想情况下,这应该是对nowk的答案的评论,但我找不到评论框。因此另一个答案)

答案 1 :(得分:0)

尝试更改此内容:

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

到此:

if @search.save

答案 2 :(得分:0)

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

您发送了身份9036304997196d83b20cba82a0cc67b8,但您的模型正在保存97894f26ba36761d04575260b132c230

为什么您的permalink更新的值不同?你的permalink setter是否在重新分配时重新生成?

如果是这种情况,则可以解释为什么您会在第2个相同的nil请求中获得id