Ответы пользователя по тегу Ruby on Rails
  • Как индексировать элементы для частого изменения очереди?

    Если у вас не постоянно изменяемые индексы по много раз в секунду, а так же не таблица из миллиона строк, то массовый апдейт всех индексов выше или ниже нового значения вполне хорошее решение.
    То есть если вы хотите вставить элемент и дать ему индекс 5, то перед вставкой вам нужно выполнить запрос
    upate table_name set position = position + 1 where position >= 5

    При такой схеме при удалении элемента ничего с остальными элементами делать не нужно.

    Решение оставлять "зазор между индексами" в 10-100-1000 и т.д., или делать индексы дробными совершенно не приемлимо. Оно не надёжно в долгосрочной перспективе.

    И да, если говорить о типовых задачах, то эта задача типовая.
    Есть хорошим гем acts_as_list, который делает как раз нужное. Использует он способ, который я описал ваше.
    Ответ написан
    3 комментария
  • Почему не работает "не" в ограничениях в роутинге rails?

    У вас `authorized` это лямбда. Тоесть это функция, которая будет выполняться каждый раз, когда запрос придёт в рельсы.
    А вот это `!authorized`, это отрицание от лямбды, оно всегда будет ложью. Это не отрицание результата выполнения лямбды, это отрицание для самого объекта лямбды.

    2.3.1 :001 > ->() { false }
     => #<Proc:0x00000001f744e0@(irb):1 (lambda)>
    2.3.1 :002 > !(->() { false })
     => false
    Ответ написан
    2 комментария
  • Как вывести только уникальные записи последней связи?

    Если вопрос о том, как сделать uniq для коллекции, то
    Model1.includes(:model2).map { |item| item.model2.name }.uniq.each { ... }

    или
    Model1.includes(:model2).uniq { |item| item.model2.name }.each { ... }


    Если же о том, как вообще сделать выборку, то лучше использовать вариант от fairoj выше
    Ответ написан
    Комментировать
  • Как сделать URL с датой, как на Meduza?

    За формирование урла отвечает метод to_param в ActiveRecord модели.
    Для примера из meduza метод to_param выглядел бы примерно следующим образом

    class Article < ...
      # ...
      def to_param
        "#{created_at.year}/#{created_at.month}/#{created_at.day}/#{transliterated_title}"
      end
      # ..
    end


    Но одного этого недостаточно, чтобы всё начало работать. В контроллере теперь нужен какой-то механизм, который сможет по строке "2016/10/11/sgorevshiy-flagman-perezhivet-li-samsung-proval-s-galaxy-note-7".

    И тут есть два варианта.

    1. В первом варианте в методе to_param добавляется id к строке вот так
    def to_param
      "#{created_at.year}/#{created_at.month}/#{created_at.day}/#{id}-#{transliterated_title}"
    end

    или вот так
    def to_param
      "#{created_at.year}/#{created_at.month}/#{created_at.day}/#{transliterated_title}-#{id}"
    end


    В таком случае в контроллере извлекаем из строки id и ищем по нему модель в базе.

    2. Во втором варианте в модель добавляется поле, которое обычно называют либо permalink, либо slug. И в модели в before_save колбеке заполнятся это поле.
    before_save :update_slug
    
    private
    
    def update_slug
      self.slug = to_param
    end


    После чего в контроллере можно искать модель по строке.

    Лично я предпочитаю первый способ, т.к. он проще, особенно, если id размещать в самом начале строки вот так
    def to_param
      "#{id}-#{transliterated_title}"
    end

    Тут поиск модели превращается в обычный find.
    @resource = Article.find params[:id].to_i

    Для автоматизации второго способа есть гемы permalink и friendly_id.
    Ответ написан
    Комментировать
  • RSpec Rails - почему в features проверяются не все тесты?

    Проходят оба expect. В feature тестах scenario является синонимом it из обычных тестов.
    Если rspec выдал в логи, что тест прошёл, значит выполнилось всё, что в нём написано.
    Чтобы убедиться в этом, попробуйте выполнить следующий код

    scenario "root page" do
      visit root_path
    
      puts 'A'
      expect(page).to have_link("Login", href: login_path(locale: I18n.locale))
      puts 'B'
      expect(page).to have_link("Signup", href: signup_path(locale: I18n.locale))
      puts 'C'
    end
    Ответ написан
    4 комментария
  • Чем отличаются данные конструкции?

    Отличия есть. В первом случае код внутри класса будет видеть константы из модуля (и имена вложенных классов соответственно), а втором - нет.
    Пример:
    module A1
      TEST = 'zz'
    end
    
    module A1
      class B1
        def foo
          TEST
        end
      end
    end
    
    module A2
      TEST = 'zz'
    end
    
    class A2::B2
      def foo
        TEST
      end
    end


    A1::B1.new.foo #> "zz"
    A2::B2.new.foo #> NameError: uninitialized constant A2::B2::TEST
    Ответ написан
    1 комментарий
  • Как протестировать вызов маилера?

    let(:confirm_oauth) { double deliver_now: nil }
    before do
      allow(ConfirmOauth).to receive(:email_confirmation)
        .and_return confirm_oauth
    end
    subject! { do_something_that_calls_mailer }
    
    it do
      expect(ConfirmOauth).to have_received(:email_confirmation).with user
      expect(confirm_oauth).to have_received :deliver_now
    end


    Другой способ - это метод receive_message_chain https://relishapp.com/rspec/rspec-mocks/docs/worki... Он подойдёт, если не нужно проверять с какими параметрами были вызваны промежуточные методы.
    Ответ написан
    Комментировать
  • Как правильно разделить доступ к views для разных ролей на Rails 4?

    Вам нужен метод prepend_view_path, в котором в зависимости от роли выставляйте нужный путь.
    apidock.com/rails/AbstractController/ViewPaths/Cla...

    Если у вас разные вьюшки для разных ролей, то скорее всего и разный функционал в этих вьюшках. Возможно, в таком случает стоит подумать на тем чтобы разнести всё и по разным контроллерам. Тогда проблема со вьюшками исчезнет сама собой.

    class Manage::SomeController < ...
      layout 'manage_application'
    end


    Admin::SomeController

    Director::SomeController
    Ответ написан
    1 комментарий
  • Где найти хороший туториал по регулярным выражениям в руби?

    Ответ не совсем на ваш вопрос, но...
    Почитайте лучше книгу "Регулярные выражения" от Джеффри Фридла www.ozon.ru/context/detail/id/4066500
    Написана она интересно и очень доступным языком. После прочтения и осознания этой книги никакие туториалы вам уже не понадобятся, как и не будет для вас разницы, на каком языке использовать регулярные выражения: на руби, яваскрипте, пхп или c#.
    Ответ написан
    Комментировать
  • Как в Rails ловить ActionController::RoutingError при отдаче изображений на девелопменте?

    Из рельс в общем-то никак, т.к. изображения на продакшене должны отдаваться nginx'ом. У рельс есть настройка для продакшена, насильно отключающая отдачу статики
    # Disable Rails's static asset server (Apache or nginx will already do this)
    config.serve_static_files = false

    Если вы всё же по каким-то соображениям отдаёте статику рельсами, что категорически неверно, то в ApplicationController можно сделать перехватчик эксепшена
    rescue_from ActionController::RoutingError, with: :routing_error

    и в нём проверять, урл картинки это или нет.
    Ответ написан
    4 комментария
  • Как отчлючить token authenticity?

    В контроллере:
    skip_before_action :verify_authenticity_token
    Ответ написан
    Комментировать
  • Как правильно составить запрос?

    либо фильтровать сразу в запросе

    Post
      .where.not(id: @posts_hot.map(&:id))
      .where.not(id: Post.where(post_block_id: 2)) # magic number anipattern. лучше заменить на константу
      .where.not(id: Post.joins(:post_asset).where.not(post_asset: { quote: nil }))
      .order(created_at: :desc)
      .limit(15)


    либо отфильтровать после запроса в коде

    Post
      .includes(:post_asset)
      .where.not(id: @posts_hot.map(&:id))
      .order(created_at: :desc)
      .limit(15)
      .select { |post| post.post_block_id != 2 }
      .select { |post| post.post_asset.try :quote }
    Ответ написан
    7 комментариев
  • Как правильно настроить яндекс.метрику на работу с turbolinks?

    вебвизор в метрике не пробовал, а всё остальное трекается так:

    $(document).on('page:before-change', function() {
      window.turbolinks_referer = location.href;
    });
    
    $(document).on('page:load', function() {
      if (window.turbolinks_referer) {
        // yandex metrika
        if (window.yaCounter7915231) {
          window.yaCounter7915231.hit(location.href, $('title').html(), window.turbolinks_referer);
        }
        // google analytics
        if (window.ga) {
          window.ga('send', 'pageview');
        }
      }
    });
    Ответ написан
  • Турнирная сетка на Rails?

    Это не гем, но возможно вам поможет https://github.com/morr/shikimori_contests
    В репозитории находится код реализации турниров с этого сайта shikimori.org/contests

    Турниры умеют работать с произвольным числом участников и по разных схемам (два поражения на вылет / одно поражение на вылет / круговая схема, когда играют все со всеми)
    Ответ написан
    Комментировать
  • Ruby on Rails: где хранить медиафайлы?

    делается это созданием каталога на сервере, который лежит отдельно от приложения и при каждом деплое симлинкается в public каталог

    подробнее:

    если файлы заливают пользователи, то загружать их можно гемами paperclip или carrierwave
    оба гема будут заливать файлы куда-то, например в каталог public/screenshots

    этот каталог вам нужно будет засунуть в .gitignore, чтобы он не попал в репозиторий

    приложение вы деплоите, надеюсь, через capistrano

    на продакшен сервере в каталоге, куда будет идти деплой, в shared каталоге нужно будет создать ваш каталог
    и задать в конфиге капистрано, чтобы капистрано делал симлинк из #{shared_path}/screenshots в #{release_path}/screenshots

    пример куска конфига для capistrano 3: take.ms/NwlI9
    надо задать лишь имена файлов и каталогов, а капистрано затем всё сделает сам
    Ответ написан
    Комментировать
  • Почему не получается наладить работу spork совместно с rspec для Rails4?

    Всё выглядит правильно, а судя по этому https://github.com/sporkrb/spork/issues/199 нужно просто подождать подольше после запуска spork'а.

    p.s. windows не самая лучшая операционная система для разработки на rails, у вас будут ещё десятки и сотни подобных ситуаций, когда что-то или не работает совсем, или работает не так, как должно, и ничего вы с этим не поделаете. если нет возможности сменить виндовс на мак/линукс, то как вариант можно установить виртуалку с ubuntu server и запускать рельсы оттуда, а редактировать код из винды.
    Ответ написан
    Комментировать
  • Связка из Windows и Ubuntu (server) для разработки Rails-приложения?

    странный лог консоли, как будто rails s выполнило не запуск сервера, а создание нового проекта.
    как решить проблему подсказать не могу, но могу написать, как можно попробовать её обойти, поставив руби через rvm:
    1. установите rvm https://rvm.io/ \curl -L https://get.rvm.io | bash -s stable
    2. через rvm установите нужную версию руби (2.0 например rvm install ruby-2.0.0-p247)
    3. переключитесь на установленную версию руби rvm use ruby-2.0.0-p247
    4. установите гем рельс gem install rails
    5. cd /mnt/hgfs/github/rin
    6. bundle install
    7 команда rails server теперь должна отработать
    Ответ написан
    Комментировать
  • Ruby on Rails vs Node.js: что лучше выбрать?

    Ноду с рельсами сравнивать нельзя вообще. Никоим образом.
    Аналог ноды в руби это https://github.com/eventmachine/eventmachine - фреймворк для асинхронной работы с сокетами. Всё, что можно сделать в ноде, можно сделать и в eventmachine.
    Ресурсов eventmachine будет съедать побольше ноды. Не на порядки, но в разы. Это минус, критичный лишь в очень редких ситуациях. Плюсом eventmachine будет то, что использоваться будет не яваскрипт, а руби и вся сопутствующая руби инфраструктура - тысячи библиотек(гемов) на все случаи жизни.

    Вы не написали, для какой цели вы выбираете фреймворк, но могу предположить, что для какого-то вебпроекта, для 99.99% из которых ни нода, ни eventmachine не подойдут в виду своей асинхронности и низкоуровневости.

    Если вам нужен фреймворк для написания веб приложения, то у rails в среде ruby/nodejs конкурентов просто нет. express.js/sinatra и другие мини фреймворки для чего-то серьёзного рассматривать не стоит, хотя если вы любите выдумывать велосипеды и всё делать руками, то можно.
    Ответ написан
    3 комментария