rails如何在Model中引用当前对象

gro*_*ble 3 ruby ruby-on-rails rails-activerecord

这是另一个问题的延续,但由于它有所不同,我虽然最好将其重新发布为一个新问题:

老问题


我正在从Hartl教程的twitter应用程序中添加测验功能,并拥有以下模型:

用户与教程几乎相同:

class User < ActiveRecord::Base

  has_many :followed_users, through: :relationships, source: :followed

  has_many :takens, dependent: :destroy
  has_many :questions, through: :takens
end
Run Code Online (Sandbox Code Playgroud)

使用的是用户ID的问题ID表:

class Taken < ActiveRecord::Base
  belongs_to :user
  belongs_to :question

end
Run Code Online (Sandbox Code Playgroud)

问题没什么好处的:

class Question < ActiveRecord::Base
  attr_accessible :category, :correct, :option1, :option2, :option3, :qn
end
Run Code Online (Sandbox Code Playgroud)

我希望能够按照他们所进行的测试次数来显示follow_users和followers.在控制台中,这可以通过:

User.find_by_id(1).question_ids.count
Run Code Online (Sandbox Code Playgroud)

然后我可以这样做:

User.find_by_id(1).followers.first.question_ids.count
Run Code Online (Sandbox Code Playgroud)

在控制台中获取单个关注者的计数.

我觉得我差不多了.

如何通过'takens'计数对关注者和follow_users进行排序?(我也在看cache_count,起初看起来很有希望,但可能不是我需要的......)


结束旧问题

这是另一个问题的答案:通过在其他表上计数的rails顺序

我在User.rb中使用了这样的方法:

def users_sort_by_taken
User.find_by_sql("SELECT users.*
                  SELECT users.*
                  FROM users INNER JOIN takens
                  ON users.id = takens.user_id
                  GROUP BY users.id
                  ORDER BY count(takens.user_id) DESC")
end
Run Code Online (Sandbox Code Playgroud)

在users_controller.rb中调用它,如下所示:

def following
    require 'will_paginate/array'
    @title = "Following"
    @user = User.find(params[:id])
    #@users = @user.followed_users.paginate(page: params[:page])
    @users = @user.users_sort_by_taken.paginate(page: params[:page])
    render 'show_follow'
end
Run Code Online (Sandbox Code Playgroud)

(作为参考,注释掉的行来自Hartl教程)一切都很好,但现在用户包含在下面的列表中(因为上面的SQL).我需要一种从users_sort_by_taken中消除当前用户的方法.

我认为这可行:

WHERE (#{@current_user.id})
Run Code Online (Sandbox Code Playgroud)

在方法中,但我收到此错误:

被称为nil的id,错误地为4 - 如果你真的想要id为nil,请使用object_id

我想我可以将它作为一个参数传递...但是我不是已经将用户作为@user在以下行中?

@users = @user.users_sort_by_taken.paginate(page: params[:page])
Run Code Online (Sandbox Code Playgroud)

为什么我不能从User.rb模型中的方法引用当前用户?

或者另一种方式,我可以将current_user(或@user或用户)传递给SQL以从SQL结果中排除current_user吗?

任何帮助赞赏.

Fre*_*ung 8

每个对象都有自己的一组实例变量 - 在一个对象中设置@user或@current_user对另一个对象没有任何意义.

方法的接收者(在这种情况下是您的用户)始终以self身份提供,因此self.id可以获得用户的ID

自我实际上是隐含的 - 大多数时候你不需要它而只是写作id会导致相同的事情(只要你在该用户的实例方法中)


Mis*_*cha 6

要引用@userid模型,你可以简单地使用:

self.id
Run Code Online (Sandbox Code Playgroud)

  • 别客气.你甚至可以省略`self`并且只使用`id`,但为了清楚起见,你可能想要使用`self`.如果在方法的定义中使用`self`,它就变成了一个类方法.但在实例方法中,`self`指的是当前实例. (2认同)