无法使用 rails4 中的 user_id 和 text_id 获取数据库列的值

unable to fetch the value of database column using user_id and text_id in rails4

你好,在下面的 erb 代码中,我想使用 current_user.id 和 text_id 获取收藏夹 table 中存在的列 counter 的值。模型关系如下

我是 rails 的新手,我不确定我们是否可以获取视图中的值。请帮忙。

<p>
  All Favorites
    <% if ***current_user.favorite.counter == ?*** %>
      <%= link_to #do something %>
    <% else %>
      <%= link_to #do something else %>
    <% end %>
</p>

User.rb

class User < ActiveRecord::Base

  devise :database_authenticatable, :registerable,
     :recoverable, :rememberable, :trackable, :validatable

  has_many :favorites
  has_many :favorite_texts, through: :favorites, source: :favorited, source_type: 'Text'

Favorite.rb

class Favorite < ActiveRecord::Base

  belongs_to :favorited, polymorphic: true
  belongs_to :user

收藏夹 table 具有以下数据库列

id | text_id | favorited_type | user_id |  created_at |  updated_at | counter 

此外 text_id 对于 user_id 也是独一无二的。

用户控制器有如下代码

class UsersController < ApplicationController
  def show
    @user = User.find(params[:id])
    @texts = current_user.favorite_texts
    @favorite_groups = @user.favorite_groups
    @fav_group = FavoriteGroup.new
    respond_to do |format|
      format.html # show.html.erb
      format.xml { render :xml => @user }
    end
  end
end

提前致谢。

统计记录

如果您想获得关联的计数,您只需执行以下操作:

current_user.favorites.count

发出 SQL COUNT(*) 查询:

SELECT COUNT(*) FROM "favorites" WHERE "favorites"."user_id" = ? [["user_id", 1]]

但是,如果您要遍历大量记录,这可能会出现问题,因为这会导致所谓的 n+1 问题。

users.all do |u|
  if u.favorites.count.zero? # will cause a SQL query for each iteration!
  end
end

ActiveRecord::Relation#size 另一方面是聪明的,如果它们已经被加载,就会计算内存中的记录。

def size
  loaded? ? @records.length : count(:all)
end

所以您可以将它与 .includes 一起使用以避免 n+1 问题。

users.all do |u|
  if u.favorites.size.zero?
  end
end

计数器缓存

如果您想避免加载相关记录并同时避免 n+1 COUNT 查询,您可以向所属模型添加一个计数器缓存。

在此示例中,如果您要向用户添加 favorites_count 列,并设置收藏夹选项。向连接模型添加计数器意义不大。

class Favorite < ActiveRecord::Base
  belongs_to :favorited, polymorphic: true
  # note that counter_cache needs to be set on the belongs_to side
  belongs_to :user, counter_cache: true
end

每次插入或销毁收藏夹时 rails 现在都会更新关联的用户。但是,与 UPDATE 查询相关的成本很小。

一个问题是任何现有用户都没有计数器缓存,因此您需要遍历它们并重置缓存:

User.find_each { |u| User.reset_counters(u.id, :favorites) }

要获取视图中计数器列的值(即 html.erb ),我们必须使用以下内容

<p>
  All Favorites
    <% if current_user.favorite_texts.where(id: text.id).pluck(:counter).first == 1 %>
      <%= link_to #do something %>
    <% else %>
      <%= link_to #do something else %>
    <% end %>
</p>

pluck returns 一个数组。所以我对它使用 .first 因为我的查询总是有一个值,因为收藏夹 table 中的约束。也就是说 text.id 对于每个 user.id.

都是唯一的

所以上面returns视图中计数器列的值。谢谢