【问题标题】:Rails controller update method only works for one call, then fails?Rails 控制器更新方法仅适用于一次调用,然后失败?
【发布时间】:2011-09-14 07:31:09
【问题描述】:

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

示例:

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();
});

总结一下:

如果我在浏览器的 URL 栏中输入切换 URL,它会工作一次。如果我点击刷新它会失败并给我上述错误。

如果我使用 ajax 调用,它会工作一次。

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

我感觉这可能与 Rails 中的 GET/POST 请求有关,但我不确定?我已将范围缩小到:

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

在第一个呼叫之后的任何呼叫中重新调整 nill,但我不确定它为什么这样做?

更新 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 中的型号代码。

谢谢!

【问题讨论】:

    标签: ruby-on-rails


    【解决方案1】:

    尝试改变这个:

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

    到这里:

    if @search.save
    

    【讨论】:

    • 相同的结果...仅供参考,我已将日志输出添加到原始问题中。
    • 请发布您的Search 模型的代码——其中的某些内容会在您保存时更改永久链接。
    【解决方案2】:
    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
    

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

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

    如果是这种情况,请解释为什么您在第二次相同的id 请求中收到nil

    【讨论】:

    • 是的,你是对的!有一个 before_save 操作来创建 MD5 哈希而不是 before_create。换掉它,它按预期工作!谢谢!
    【解决方案3】:

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

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

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

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

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

    【讨论】:

    • 你不能评论其他用户的答案,除非你有更多的分数(我不记得限制)。这就是为什么你需要自己回答
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-04
    • 1970-01-01
    • 2018-10-22
    • 2020-09-24
    • 2018-01-18
    相关资源
    最近更新 更多