ActiveRecord.find(array_of_ids), сохраняя порядок

Некоторый основной functionals:

public static class Functionals
{
    // One-argument Y-Combinator.
    public static Func Y(Func, Func> F)
    {
        return t => F(Y(F))(t);
    }

    // Two-argument Y-Combinator.
    public static Func Y(Func, Func> F)
    {
        return (t1, t2) => F(Y(F))(t1, t2);
    }

    // Three-arugument Y-Combinator.
    public static Func Y(Func, Func> F)
    {
        return (t1, t2, t3) => F(Y(F))(t1, t2, t3);
    }

    // Four-arugument Y-Combinator.
    public static Func Y(Func, Func> F)
    {
        return (t1, t2, t3, t4) => F(Y(F))(t1, t2, t3, t4);
    }

    // Curry first argument
    public static Func> Curry(Func F)
    {
        return t1 => t2 => F(t1, t2);
    }

    // Curry second argument.
    public static Func> Curry2nd(Func F)
    {
        return t2 => t1 => F(t1, t2);
    }

    // Uncurry first argument.
    public static Func Uncurry(Func> F)
    {
        return (t1, t2) => F(t1)(t2);
    }

    // Uncurry second argument.
    public static Func Uncurry2nd(Func> F)
    {
        return (t1, t2) => F(t2)(t1);
    }
}

не делают много хорошего, если Вы не знаете, как использовать их. Чтобы знать, что, необходимо знать то, для чего они:

93
задан Mike Woodhouse 5 November 2009 в 19:48
поделиться

4 ответа

Ответ только для mysql

В mysql есть функция, называемая FIELD ()

Вот как вы можете использовать ее в .find ():

>> ids = [100, 1, 6]
=> [100, 1, 6]

>> WordDocument.find(ids).collect(&:id)
=> [1, 6, 100]

>> WordDocument.find(ids, :order => "field(id, #{ids.join(',')})")
=> [100, 1, 6]

For new Version
>> WordDocument.where(id: ids).order("field(id, #{ids.join ','})")
69
ответ дан 24 November 2019 в 06:14
поделиться

Not possible in SQL that would work in all cases unfortunately, you would either need to write single finds for each record or order in ruby, although there is probably a way to make it work using proprietary techniques:

First example:

sorted = arr.inject([]){|res, val| res << Model.find(val)}

VERY INEFFICIENT

Second example:

unsorted = Model.find(arr)
sorted = arr.inject([]){|res, val| res << unsorted.detect {|u| u.id == val}}
5
ответ дан 24 November 2019 в 06:14
поделиться

Под капотом find с массивом идентификаторов сгенерирует SELECT с WHERE id IN ... предложение, которое должно быть более эффективным, чем цикл по идентификаторам.

Таким образом, запрос удовлетворяется за один переход к базе данных, но предложения SELECT без предложений ORDER BY не отсортированы. ActiveRecord понимает это, поэтому мы расширяем наш find следующим образом:

Something.find(array_of_ids, :order => 'id')

Если порядок идентификаторов в вашем массиве произвольный и значимый (т.е. вы хотите, чтобы порядок возвращаемых строк соответствовал вашему массиву независимо от последовательности идентификаторов, содержащихся в нем), то я думаю, что вы станете лучшим сервером, постобработав результаты в коде - вы можете создать предложение : order , но это будет чертовски сложно и совсем не раскрывает намерения.

1
ответ дан 24 November 2019 в 06:14
поделиться

В find (: order => '...') есть предложение заказа, которое делает это при выборке записей. Здесь вы также можете получить помощь.

текст ссылки

-4
ответ дан 24 November 2019 в 06:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: