【问题标题】:how does devise current_user work?设计 current_user 如何工作?
【发布时间】:2013-01-27 14:22:31
【问题描述】:

我想了解设计 current_user 方法的工作原理,因为我想将其推广到其他模型,这些模型将允许使用 current_forum 或 current_forum_thread 等代码。

更具体地说,我正在尝试在 Rails 中实现一个聊天论坛。我有一个页面显示特定讨论线程的所有帖子(目前没有)。同一页面嵌入了新的帖子表单。调试(参数)显示:

action: show
controller: discussions
forum_id: '1'
id: '1'

discussion: !ruby/object:Discussion
  attributes:
    id: 1
    title: first discussion (thread)
    forum_id: 1

因此,posts 控制器中的 create 方法应该知道讨论 id 是什么。然而,控制器中的这段代码不起作用。

  1. @discussion = Discussion.find(params[:id])
  2. @post = @discussion.posts.new(params[:post])
  3. if @post.save
  4.  flash[:success] = "Discussion post created!"
  5.  redirect_to '#'
  6. else
  7.  render '#'
  8. end

第 1 行引发错误:

Couldn't find Discussion without an ID

此外,经过检查发现@discussion 变量始终为 NIL。

【问题讨论】:

    标签: ruby-on-rails devise


    【解决方案1】:

    我认为它更像是一个辅助函数,设计的方法是通过会话获取 ID,但你可以通过 params 哈希来做同样的事情, 即

    module ApplicationHelper
      def current_forum_thread
       Thread.find(params[:id])
      end
    end
    

    这对你有用吗?

    【讨论】:

    • 您的代码的等效项会引发错误 - 找不到没有 ID 的 -
    • 你在线程的页面中吗? params[:id] 在页面内有效,您可以在视图内写入 <%= debug params %> 以查看 params 所持有的内容。也许它没有设置为 :id?
    • 是的。创建新帖子的表单嵌入在线程(讨论)页面中。
    • params[:id] 返回 nil 吗?
    • debug(params) 表明 :id 有一个有效数字。再次考虑您的第一个问题,即使创建帖子视图嵌入在讨论视图帖子中,创建也是在帖子控制器中处理的。如何告诉 post 控制器创建调用的来源?
    【解决方案2】:

    我将before_filter :authenticate_user! 放在每个控制器的顶部,然后执行以下操作:

    current_user.posts.new(params)
    

    这也需要关系User has_many :posts

    似乎有效(但不确定这是否是最好的方法)。

    另外,您的错误似乎意味着您的 prarms[:id] 为 nil,因此请检查它是否正确传递。您应该能够在日志中看到这一点。

    # Discussions controller - show action
    @discussion = Discussion.find(params[:id])
    render ...
    
    # Discussion show view
    %ul
      - @discussion.posts.each do |post|
        %li= post.content # to output list of posts
    = form_for @discussion.posts.new do |f|
      = f.input :content
      = f.submit
      # form to create new post related to this discussion
    
    # Post controller - create method
    @post = Post.new(params[:id])
    @post.save!
    render ...
    

    【讨论】:

    • 这似乎是问题所在。我在哪里可以检查 :id 变量的传递?
    • 我只看到您将 id = 1 的 Discussion 放入数据库。不知道你是如何得到它的。如果您定义了资源 :discussions - 您可以像这样获得它的 ID:http://localhost:3000/discussions/1。这可能就是您的讨论显示操作 url 的外观,这就是表单所在的位置。我的疯狂猜测是您在帖子创建表单中使用form_for Post.new。如果是这种情况 - 你应该尝试做form_for @discussion.posts.create(或form_for @discussion.posts.new)。这将自动将 id 传递给 Post,因此您无需先通过 ID 找到它。
    • 还是有问题。帖子的父级(“讨论”)本身是一个嵌套资源(嵌套在“论坛”下)这一事实与这个问题有什么关系吗?正如 Guy 所说,我可以使用隐藏字段来设置 thread_id,但我想暂时搁置该解决方案。
    • 刚刚添加了我会怎么做
    【解决方案3】:

    在这个实现中使用 current_id 和线程似乎过于复杂,因为它看起来像一个非常简单的嵌套资源。

    帖子没有保存,因为它找不到讨论。由于您在 Post 控制器而不是 Discussion 上,因此您需要寻找与

    的讨论
    @discussion = Discussion.find(params[:discussion_id])
    

    您搜索它的 :id 来自帖子的参数。它没有找到任何东西,因为您可能有更多讨论的帖子。如果它确实找到了一些东西,那就是找到了错误的东西。

    使嵌套路由工作的检查清单上的另一件事是使路由正确。用“rake routes”检查它们,但它应该如下所示:

    resources @discussions do
       resources @posts
    end
    

    这将添加路由,以便您的表单(应类似于<%= form_for [@discussion, @post] do |f| %>)可以发布/放入讨论帖子路径。

    像您使用的那样使用 current_id 确实是范围界定,而且有点混乱,Ryan Bate 有一个很棒的视频关于多租户的范围 http://railscasts.com/episodes/388-multitenancy-with-scopes

    【讨论】:

      猜你喜欢
      • 2016-02-01
      • 2011-10-11
      • 1970-01-01
      • 1970-01-01
      • 2014-02-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多