2016-03-22 18 views
1

Merhaba, aşağıdaki erb kodunda Current_user.id ve text_id kullanarak favori tabloda bulunan bir sütunun counter değerini almak istiyorum. Modellerin ilişkisi aşağıdaki gibidir.kullanıcı_id ve text_id kullanarak veritabanı sütunu değerini alamıyor 4

Raylara yeniyim ve görünümündeki değeri getirip getiremeyeceğimizden emin değilim. Lütfen yardım et.

<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 

Favori tabloda aşağıdaki veritabanı sütunları

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

Ayrıca text_id user_id için benzersizdir

sahiptir.

kullanıcı denetleyici aşağıdaki kodu önceden

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 

Teşekkür vardır.

+0

İsteğinizi tam olarak anladığımı bilmiyorum, ancak bu kod: "current_user.favorites.where (favorited_type: 'Text', favorited_id: text_id) .first.counter", "sayaç" değerinin Bir kullanıcı ve bir Metin bağlayan favori kayıt – MrYoshiji

+0

Evet text_id ve user_id kullanılarak getirilen 'counter' değerini getirmek istiyorum. –

+0

@MrYoshiji Denetleyicide sizin tarafınızdan önerilen yolu takip ettiğimde ve bir değişkende "where" deyimi tarafından getirilen verileri sakladığınızda ve "sayaç" a erişmeyi denediğimde, "NilClass" için "tanımlanmamış" yöntemi "sayacı" alıyorum. Doğru şekilde yapıp yapmadığımdan emin değilim. –

cevap

0

Sayma kayıtları

Eğer sadece yapacağını dernek sayısını almak istiyorsanız

: SQL COUNT(*) sorgu gönderildiğinde

current_user.favorites.count 

:

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

Ancak bu olabilir n+1 sorunu olarak adlandırılan neden olacak gibi kayıtlar çok sayıda yinelenen, sorunlu. diğer yanda

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

ActiveRecord::Relation#size akıllı ve onlar zaten yüklenmiş varsa bellekte kayıtları sayar.

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

Yani n + 1 sorunu önlemek için .includes ile birlikte kullanmak.

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

Sayaç

Eğer ilişkili kayıtları yüklenirken önlemek istiyorsanız

önbelleğe ve n + 1 COUNT sorgular aynı zamanda kaçınmak de size sahip olma modeline karşı önbelleği ekleyebilir.

Bu örnekte, kullanıcılara bir favorites_count sütun eklerseniz ve sık kullanılanlar seçeneğini ayarlarsanız. Birleştirme modeline bir sayaç eklemek çok az anlam ifade eder.

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 

Sık Kullanılan bir ray taktığınızda veya imha ettiğinizde şimdi ilgili kullanıcıyı güncelleyecektir. Bununla birlikte, UPDATE sorgusuyla ilgili küçük bir maliyet var.

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

Kayıtları alırken ilişkilendirmenin bir sayısını alan özel bir 'SELECT' deyimini kullanmayı içeren üçüncü bir yöntem vardır. Ancak bununla biraz beklemek isteyebilirsiniz. – max

+0

Sık kullanılanlar tablosunda bir sütunun değerini almak için bakıyordum. Her neyse bilgi ve yardım için teşekkürler. Vurdum ve yargılanmayı denedim ve en sondaki sorgumla ilgili çözümü aldım, aşağıda yanıt olarak yayınlayacağım. –

0

görünümünde sayaç sütunun değerini almak için (yani html:

Bir yakalamak onlara yineleme ve önbellek sıfırlamak gerekir böylece mevcut tüm Kullanıcı sayaç önbelleğe sahip olmayan olmasıdır .erb) biz

<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

bir dizi döner aşağıdaki kullanmak gerekir. Bu yüzden .first kullanıyorum çünkü sık kullanılanlar tablosundaki kısıtlama nedeniyle sorgum her zaman bir değere sahip olacaktır. Bu, text.id her bir user.id için benzersizdir.

Yukarıdaki nedenle, görünümde sayaç sütununun değeri döndürülür. Teşekkürler.

İlgili konular