Ответы пользователя по тегу Ruby on Rails
  • Очередь задач resque. Одна большая или несколько мелких?

    c3gdlk
    @c3gdlk
    Ментор в http://rubyboost.ru/
    Нагрузка возрастает потому что задачи начинают обрабатываться параллельно, причем каждая в новом процессе.

    Идеальный вариант, переехать на Sidekiq - он и сам по себе намного быстрее и при необходимости можно настроить количество задач, которые выполняются одновременно.

    Если такой возможности нет, то можно запускать одну большую задачу, отлавливать падение синхронизации через begin rescue чтобы не нарушать общий процесс. Для всех отловленных запустить отдельную задачу. Если их не много, то нагрузка возрастет только на время их обработки
    Ответ написан
    3 комментария
  • Почему в Rails 4.2.6 вместо DELETE у меня отправляется GET?

    c3gdlk
    @c3gdlk
    Ментор в http://rubyboost.ru/
    Метод подставляется с помощью javascript

    Он должен быть включен и в вашем манифесте должны бить подключены следующие файлы

    app/assets/javascripts/aplication.js

    #= require jquery
    #= require jquery_ujs
    Ответ написан
    Комментировать
  • Кто проходил удачные дистанционные курсы по Ruby on rails?

    c3gdlk
    @c3gdlk
    Ментор в http://rubyboost.ru/
    Могу ответить с другой стороны, со стороны того, кто эти курсы ведет. С недавнего времени мы начали обучать всех желающих в стремлении найти себе нового сотрудника. Первый курс был основан на моем личном опыте, Второй, который мы начинаем, основан уже на анализе проблем новичков - мы выделили примерно 50 стандартных ошибок/вопросов, которые возникают у каждого новичка.

    Пообщайтесь с авторами курсов, поинтересуйтесь, как они решают Вашу задачу. Как правило, чтобы попасть на работу стажером, достаточно туториала Хартла и одного простенького приложения написанного самостоятельно.
    Если есть хороший опыт с хорошими PHP фреймворками, то можно и джуном попасть. Может быть и правда проще получить опыт в другой технологии, а потом найти интенсив который поможет быстро перейти.
    Ответ написан
    Комментировать
  • Как правильней записывать в БД связи?

    c3gdlk
    @c3gdlk
    Ментор в http://rubyboost.ru/
    можно использовать accept_nested_attributes - https://robots.thoughtbot.com/accepts-nested-attri...
    Ответ написан
    Комментировать
  • Как в одной таблице сделать два внешних ключа?

    c3gdlk
    @c3gdlk
    Ментор в http://rubyboost.ru/
    Примеры к ответу nbekseitov
    Полиморфная связь
    class Buyer < User
    end
    
    class Seller < User
    end
    
    class Order
      belongs_to :buyer
      belongs_to :seller
    end


    Внешний ключ
    class Order
      belongs_to :buyer, foreign_key: :buyer_id, class_name: User
      belongs_to :seller, foreign_key: :seller_id, class_name: User
    end


    Сложно сказать какой вариант правильный, зависит от задачи и структуры проекта. Второй вариант намного проще и довольно часто его достаточно. В первом варианте Вы с самого начала будете явно разделять логику продавца и покупателя между двумя классами, что положительно скажется на качестве кода в дальнейшем.
    Ответ написан
    Комментировать
  • Правильно ли сделано кэширование?

    c3gdlk
    @c3gdlk
    Ментор в http://rubyboost.ru/
    Функция cache может принимать или уже готовый ключ для хранения, или, как в Вашем случае, экземпляр модели. В этом случае ключ будет построен из id и updated_at, поэтому updated_at должен быть во всех моделях.

    Еще в Вашем коде
    - menu = render_menu(code)

    вызывается до первого кеша, в этом случае в первом вызове кеша нет никакого смысла

    Проще всего посмотреть логи консоли, в случае с кеширование рельса пишет какие фрагменты использует
    Ответ написан
  • Как организовать синхронизацию данных БД между разработчиками в период разработки?

    c3gdlk
    @c3gdlk
    Ментор в http://rubyboost.ru/
    Для наполнения базы тестовыми данными в рельсе используются сиды. Только их код пишется так, чтобы не просто пытались засунуть данные в базу, а перед этим поискать аналогичные. Если данные слишком сложные - те же сиды, но сами значения хранятся в YML файлах в какой-нибудь папке db/fixtures.

    Если и этого не хватает - можно посмотреть в сторону https://github.com/harrystech/seed_migration

    Еще можно писать rake таски типа db:populate:feature_name - такой подход позволит наполнять базу только нужными данными. Ну и соответсвенно будет один общий таск, который прогонит все populate
    Ответ написан
    Комментировать
  • Как в Ruby on Rails подключиться к шрифту создав папку fonts?

    c3gdlk
    @c3gdlk
    Ментор в http://rubyboost.ru/
    Ответ, который Вы отметили не совсем верный. При деплое на сервер происходит генерация ассетов с дайджетами.

    Правильно:
    src: font-url(rouble.ttf);
    Ответ написан
    Комментировать
  • Ruby and Rail связать две таблицы?

    c3gdlk
    @c3gdlk
    Ментор в http://rubyboost.ru/
    согласно конвенции rails не может быть таблички с именем posts_category

    может быть post_categories - когда у одной категории много постов, связь 1 ко многим и могут быть таблицы categories и posts_categories - связь многие ко многим

    Т.е в вашем случае скорее всего должна быть табличка post_categories и везде belongs_to :post_category
    Ответ написан
    Комментировать
  • Как отрендерить метод со статусом?

    c3gdlk
    @c3gdlk
    Ментор в http://rubyboost.ru/
    Мы обычно примерно так делаем. Добавляем методы в базовый контроллер

    def respond_with_400(exception)
        render json: { success: false, all_errors: ['The user has not authorized application'] }, status: 400
      end
    
      def respond_with_404(exception=nil)
        render json: { success: false, all_errors: [t('errors.not_found')] }, status: 404
      end
    
      def respond_with_500(exception)
        render json: {success: false, all_errors: [t('errors.something_went_wrong')], debug: exception.to_s}, status: 500
      end
    
      def respond_with_success(resource=nil, status=200)
        result = {success: true}
        result.merge!(:"#{resource.class.name.underscore}" => {id: resource.id}) if resource.present?
    
        render json: result, status: status
      end
    
      def respond_with_errors(resource=nil, status=422, debug=nil)
        result = {success: false}
    
        result.merge!(errors: resource.errors.messages, all_errors: resource.errors.full_messages)  if resource.present?
        result.merge!(debug: debug) if debug.present?
    
        render json: result, status: status
      end
    Ответ написан
    Комментировать
  • Как вывести в теме и теле письма данные из переменной?

    c3gdlk
    @c3gdlk
    Ментор в http://rubyboost.ru/
    Там где шаблон письма из базы подставляется в тело письма нужно использовать ERB процессор при этом передав в него текущий контекст(binding)

    @tmp = 'Some value'
    email_body = ERB.new(mail_template_from_database).result(binding)
    
    mail(to: user_email,  body: email_body,   content_type: "text/html",   subject: "Email subject")
    Ответ написан
  • Более правильный способ обработки не найденной сущности?

    c3gdlk
    @c3gdlk
    Ментор в http://rubyboost.ru/
    Всегда должен быть find. А ошибка отлавливается в ApplicationController

    unless Rails.application.config.consider_all_requests_local
        rescue_from Exception, with: :respond_with_500
    
        rescue_from ActiveRecord::RecordNotFound,
                    ActionController::RoutingError,
                    ActiveRecord::RecordInvalid,
                    with: :respond_with_404
    
        rescue_from ActionController::BadRequest, with: :respond_with_400
      end
    
    def respond_with_404(exception=nil)
        redirect_to root_path
      end
    Ответ написан
    5 комментариев
  • Как правильно организовать права доступа rails?

    c3gdlk
    @c3gdlk
    Ментор в http://rubyboost.ru/
    В user_roles добавить связь к компании company_id

    В cancancan проверять доступ по конкретной компании. Чтобы передать компанию в ability из контроллера - нужно переопределить метод current_ability насколько я помню.
    Ответ написан
    Комментировать
  • Как правильно организовать nested form'у для трех моделей?

    c3gdlk
    @c3gdlk
    Ментор в http://rubyboost.ru/
    Чтобы вывести только позиции компании нужно их явно задать в контроллере

    @user.positions = @company.positions.where(user: @user)


    Но, я не думаю, что это будет работать, потому что сохранение скорее всего сотрет позиции других компаний.

    В этом случае проще написать эту логику явно
    Ответ написан
  • Что нужно знать прежде чем учить ROR?

    c3gdlk
    @c3gdlk
    Ментор в http://rubyboost.ru/
    По поводу того, что нужно знать из основ - полностью согласен с Денисом

    Хотел бы добавить свои мысли по поводу пути изучения RoR

    Довольно часто возникает вопрос в том, какую технологию стоит изучать. Обычно выбор стоит между Ruby on Rails, Python + Django и Node.js. Я считаю, что программист не должен замыкаться на одной технологии. Он должен иметь представление о смежных/новых технолоигях, и уметь, при необходимости, довольно быстро переключится на новый инструмент.

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

    Соответсвенно, в таком случае самостоятельное изучение не будет хорошим решением, потому что нужен наставник, который поможет в освоении лучших практик и не допустит велосипедостоительства.

    Лучшим путем будет практика в какой-либо конторе, с решением реальных задач. Но, тут проблема вот в чем - обычно новичек примерно 3-5 месяцев практикуется на несложных проектах, и это, на мой взгляд довольно медленно.

    Идеальным, на мой взгляд, является практика в небольшой команде. Я так начинал, у меня был очень опытный наставник, проекты заходили намного сложнее, чем я мог потянуть и мне приходилось очень быстро учиться, с чем очень хорошо помогает опытный наставник. Альтернативой может послужить практика падаваном у упытного программиста, но тут главное не упустить тот момент, когда ты уже месяц решаешь знакомые тебе задачи и не продвигаешься вперед.

    Альтернативой может послужить прохождение курсов. Я знаком с материалами курсов rubybursa.com и ror.thinknetica.com, но они не показались мне интересными. Довольно интересными выглядят https://mkdev.me/. Не знаком с материалом (их нет на торрентах=)), но блог Кирила очень интересен, и я думаю, что курсы, скорее всего, тоже на уровне, тем более там несколько курсов для различного уровня подготовки.

    Я также планирую запустить свой курс. Он будет направлен на то, чтобы достаточно быстро (примерно месяц обучения) получить практические знания, которые помогут за месяц пройти этап неинтересных проетов и попасть в разработку серьезных приложений с сильным руководителем. Если интересно - подписывайтесь на твиттер, там будут обновления. https://twitter.com/c3gdlk

    P.S. Для начала ruby учить не надо. Основы учатся за пол часа learnxinyminutes.com/docs/ruby - остальное изучается через практику.

    Самым важным пожалуй является понимание того, что такое блоки и как их использовать и осознание того, что методы класса могут быть вызваны сразу же после их описание. Т.е. все эти немного не привычные scopes, validates, has_one и belongs_to - не что иное, как вызов методов класса, которые в этот самый класс добавляют какие-то данные.
    Ответ написан
    Комментировать
  • Как сделать аутентификацию через одноклассники на Angularjs?

    c3gdlk
    @c3gdlk
    Ментор в http://rubyboost.ru/
    Мы делали на Ember.js, но смысл тот же - фреймворк можно вообще не использовать.

    https://github.com/incubus/omniauth-odnoklassniki - ставим себе гем для айтентификации.

    По нажатию на кнопку - открываем новое окно с адресом аутентефикации

    Пример кода на Ember.js но смысл должен быть понятен
    SomeApp.SocialLoginButtonView = Ember.View.extend(
      tagName: "a"
      attributeBindings: ['href']
    
      click: (e)->
        e.preventDefault()
        provider  = $(e.currentTarget).attr('href')
    
        url = "/users/auth/#{provider}?transition_to_root=true"
        window.open(
          url, '_blank',
          'width=600,height=500,location=yes,resizable=yes,scrollbars=yes'
        )
    )


    Пример контроллера

    class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
    
      layout 'blank'
    
      def facebook
        sign_in_with_oauth_data(request.env['omniauth.auth'])
      end
    
      def twitter
        sign_in_with_oauth_data(request.env['omniauth.auth'])
      end
    
      private
    
      def sign_in_with_oauth_data(oauth_data)
        unless user_signed_in?
          user =  User.find_or_create_with_oauth(oauth_data)
          sign_in :user, user
          MailWorker.perform_in(1.hour, user.id, :account_dropoff)
        end
    
        @success = current_user.register_social_profile(normalize_oauth_data(oauth_data))
        @service_name = oauth_data.provider
    
        render 'shared/social_authentication'
      end
    
      def normalize_oauth_data(oauth_data)
        { service_name: oauth_data.provider, uid: oauth_data.uid, access_token: oauth_data.credentials.token, secret_key: oauth_data.credentials.secret }
      end
    end


    Контроллер рендерит представление - javascript, который отправляет данные родительскому окну и закрывает окно авторизации

    <script type="text/javascript" charset="UTF-8">
      <% if @success %>
          window.opener.SomeApp.sendSuccess()
      <% else %>
        window.opener.SomeApp.sendFailure()
      <% end %>
    
      window.close();
    </script>
    Ответ написан
    1 комментарий
  • Почему объект не сохраняется при выполении отложенного метода через Sidekiq?

    c3gdlk
    @c3gdlk
    Ментор в http://rubyboost.ru/
    Странно, что воркер не вылетает с ошибкой, потому что для вызова воркера после сохранения нужно использовать after_commit а не after_create. В момент, когда вызывается after_create транзакция еще не закончилась и id доступен только в модели.
    Ответ написан
    3 комментария