Rails:使用belongs_to和has_many关系从2个模型中选择唯一值

时间:2015-05-02 05:37:15

标签: sql ruby-on-rails activerecord

我有2个模特:玩家和物品

玩家模型:

class Player < ActiveRecord::Base
    has_many :items
end

物品型号:

class Item < ActiveRecord::Base
    belongs_to :player
end

我试图存储一组独特的玩家(只有他们的id和名字),这些玩家创造了5个最新的项目。

如果我创建循环并逐个执行查询

,它会起作用
Item.order('created_at DESC').limit(5).first.player.id
Item.order('created_at DESC').limit(5).first.player.name

但是我想知道是否有一种方法可以使用pluck来进行没有循环的查询,并且只采用玩家的唯一值?

谢谢!

1 个答案:

答案 0 :(得分:0)

你想获得一系列创造最近5件物品的独特玩家吗?或者你想获得创造物品的5个最新独特玩家阵列?

后者将总是返回5名玩家(当你有5个或更多玩家创造了物品时),前者可能只返回一个玩家(因为他可以创造5个最近的项目)。

如果你想要5个最新项目的玩家,试试这个:

#!/usr/bin/kivy
import kivy
kivy.require('1.7.2')

from random import random
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.popup import Popup
from random import random
from random import choice
from kivy.properties import StringProperty
import time

score=0

my_popup = Popup(title='Test popup',
    content=Label(text=str(score)),
    size_hint=(None, None))


Builder.load_string("""
<Highest>:
    GridLayout:
        cols: 1
        Button:
            id: btn_0
            text: "0"
            on_press: root.new()
        Label:
""")

class Highest(Screen):
    def new(self):
        global score
        score=score+1
        self.ids['btn_0'].text = str(score)
        my_popup.open()


# Create the screen manager
sm = ScreenManager()
sm.add_widget(Highest(name='Highest'))

class TestApp(App):

    def build(self):
        return sm

if __name__ == '__main__':
    TestApp().run()

如果你想要5个最近创造过项目的独特玩家,请试试这个:

player_ids = Item.order(created_at :desc).limit(5).pluck(:player_id).uniq
Player.where(id: player_ids).pluck(:id, :name)

您甚至可以使用player_ids = Item.order(created_at :desc).pluck(:player_id).uniq.first(5) Player.where(id: player_ids).pluck(:id, :name) join关联。请注意,您现在必须使用player中的表名:

pluck

Item.joins(:player).order(created_at :desc).limit(5).pluck('players.id', 'players.name').uniq