Как стать автором
Обновить

Комментарии 45

Я в рельсах не бум-бум, но разве нельзя найти активированных пользователей прямо методом find? Перебор — это не самый клевый выход, мне кажется.
Можно. Но иногда нужно именно выбрать элементы уже существующего массива. Это не создает еще один запрос к базе.
User.find(:all) — а это не запрос к базе данных? А если пользователей туча? Если надо найти список неактивированных, то лучше его и запрашивать в бд, чем получать оттуда все и по ним бегать.
я привел самый простой пример.

если вам надо вывести сообщение на страницу «все юзеры из этого списка активированы» (не принимаем во внимание что это бесполезно) — как вы будете это делать? Делать запрос на каждого юзера?

я сделаю это одной строкой кода:
"Поздравляем, все пользователи на этой странице прошли активацию" if @users.all?{ |user| user.activated == 1 }

понял уже, там просто демонстрация работы с массивами, спасибо
Если в модели User сделать
named_scope :activated, :conditions => 'activeted = 1'
то можно писать просто User.activeted или User.activeted.find(....)
При этом во втором случае всё равно будет выполнен только один запрос к базе.
в статье должно быть сказано, что данный пример описывает как можно работать с массивом записей, а не как правильно выбирать данные из базы
Если вам надо в экшене отдавать данные и аяксом, и «по-старинке», то проверку на него можно сделать с помощью request.xhr?


Для этих целей лучше использовать respond_to.
Конструкцию @users.all?{ |user| user.activated == 1 } можно сократить до @users.all?(&:activated)
спасибо, сейчас добавлю
вообщето нельзя. в руби 0 это true, а значит будут учитываться и те у которых activated выставлен в 0 и в 1. не будут учитываться те у которых activated выставлен в false, либо вообще не задан(nil)
проверьте сами:
>> !!1
=> true
>> !!0
=> true
>> !!nil
=> false
>> !!false
=> false

«activated равен 1, значит пользователь активен» — не кошерно. надо бы сделать activated булевым (вот тогда @users.all?(&:activated) вкатит )
Да, действительно. На автомате посчитал, что activated имеет булевое значение
когда-то надо останавливаться на сокращениях, это уже на С смахивает
могли бы Вы пояснить консктруцию @users.all?(&:activated). Я так понимаю, для этого необходимо расширение класса Symbol методом to_proc с необходимым преобразованием. Это расширение из RoR? (изчаю ruby, с RoR ещё не познакомился)
Да, это рельсовое расширение. Подробнее можно почитать тут
Это не совсем так, данная фича появилась в ruby1.9 а потом была реализована так же в gem-е ActiveSupport. Так что, если нравиться такая синтаксическая глазурь, то можно сделать require нужной части ActiveSupport и наслаждаться. А лучше использовать ruby1.9.1 или даже 1.9.2.
Жесть какая-то.
Model.find(:all => Model.all

Первый пример надо делать через БД,
User.count == User.activated.count (хотя казалось бы зачем это вообще надо)

@user = User.find_by_id(current_user.id)
role = @user.role

Чем @user отличается от current_user?

З.Ы.
take, shuffle это руби типсы а не ROR-а
Model.find нагляднее для непосвященных =). Но сам пользуюсь .all, к тому же это стандарт для Rails 3

Первый пример связан с массивами, я согласен что запросы можно сделать по-другому, но опять же я говорил именно про методы select, all? и any?..

Насчет current_user согласен — копипаст кода подвел.
Не надо такой наглядности, пусть все приучаются сразу к Rails-way
Еще короче использовать метод _count_
Кроме того, нет необходимости использовать лишнюю переменную activated_users
@users = User.find(:all)
@users.count{ |user| user.activated == 1 } == @users.size
скажите честно, после хабраката вы не читали?)
Прочитал конечно. Просто предложил еще более короткий вариант. Я не прав?
самый короткий вариант это @users.all?(&:activated)
да.
но я подумал именно о подсчете.
all? и any? возвращают boolean, select — Array, в то время как count — Integer.
Хотя согласен, что задача состояла именно в возвращении булева зачения
НЛО прилетело и опубликовало эту надпись здесь
Почитал статью, и этот комментарий и подумал решить подумать об изучении Ruby…
вы еще haml не видели )))
haml-lang.com/
HAML на самом деле удобный шаблонизатор, сначало я тоже был в ужасе =)
да я и не спорю. нарадоваться им не могу
Вопрос скорее топик-кастеру, но спрашиваю здесь, раз именно здесь зашёл вопрос про изучение.

Насколько большое расхождение между Ruby/Rails && Groovy/Grails?
Имеет смысл изучать оригинальный RoR или можно начинать с GoG?
Насколько это принципиально?
Все познается в сравнении. В интернете масса статей Ruby vs Groovy. Лично я выбрал для себя Ruby, это мой язык №1, и разработка на нем доставляет мне удовольствие.

А изучать Groovy, из кода которого повсюду торчат уши Явы, лично у меня желания нет).

Для начала можете сделать простое приложение, например, блог — сначала на Рельсах, потом на их «клоне». Что больше понравится — на том и останавливайтесь =)
Текст валидации для моделей можно локализировать без добавления :message. Все просто:
activerecord.errors.models.[model_name].attributes.[attribute_name]
Например
activerecord.errors.models.user.attributes.name.blank — модель user, атрибут name, текст для сообщения blank (validates_presence_of :name).
>> Еще один полезный метод — это verify. Судя по названию, он служит для удостоверения, что на контроллер пришел правильный запрос.

также (и даже лучше) это ограничивать через роуты. Пример:
map.test '/test', :controller => :test, :action => :show, :conditions => {:method => :post}
tips: кстати array.length в несколько раз быстрее array.size
а так же:
@users.all?(&:activated) вызовет создание объекта класса Proc для каждого объекта из массива, что приведет к расходу памяти у снижению производительности
вариант @users.all?{|u| u.activated } не вызовет такого эфекта, нои выглядит как-то не так лаконично…

но это, как и описанный в вашем комменте случай, не имеет значения для повседневных задач
эм, а вы прям так в этом уверены и proc создается не один раз? интересно было бы послушать подробнее.
хорошая идея, сейчас добавлю про методы count — length — size
Судя по документации, кстати, length == size, а вот count хоть и функциональнее, но медленнее
Что за мифы и легенды такие? ) это два абсолютно одинаковых метода.
попробуйте:
ar = []; 10000.times { ar.push rand(12345) }
Benchmark.bm(7) do |x|
      x.report("size") { 10000.times { ar.size } }
      x.report("length") { 10000.times {ar.length}  }
end


у меня на 'ruby 1.9.1p243 (2009-07-16 revision 24175) [i686-linux]'
             user     system      total        real
size       0.000000   0.000000   0.000000 (  0.001275)
length   0.000000   0.000000   0.000000 (  0.000890)

тут не в несколько раз конечно, но своими глазами видел ускорение в 4 раза

объясните если знаете причину
У меня на ruby 1.8.7-249 (mac os):
user system total real
size 0.010000 0.000000 0.010000 ( 0.002396)
length 0.000000 0.000000 0.000000 ( 0.002486)
count 0.000000 0.000000 0.000000 ( 0.002455)


Думаю, результаты настолько незначительные, что можно пользоваться любым методом)
Согласно документации length это alias size-а
Спасибо, добавил к себе в память + добавил что сказанно в комментах.
Кстати еще же есть безымянные scope, которые и следует пользовать для eager loading'а — ведь в модели далеко не всегда заранее ясно, что будет делаться с результатом выборки, а лишние запросы нам ни к чему:

Car.red.scoped(:include => :users)

кстати заодно и убираем возможные недопонимания из-за названий (есть эвристический принцип, что сложные вычисления все-таки должны опознаваться по их вызову, если производительность продукта имеет значение)

Тем более что возможно, в конкретном экшне может потребоваться рекурсивный прелоад (например — хотим узнать что-то про домашних животных владельцев красных машин):

Car.red.scoped :include => { :users => :pets }
спасибо. ваша статья помогла мне избавиться от шести «велосипедиков». полюбил ruby еще сильнее.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Изменить настройки темы

Истории