Подтвердить что ты не робот

Почему иногда возникает недостающая частичная ошибка, когда файл существует?

Во время выполнения тестов на огурцы время от времени он прерывается с перерывами. Ошибка:

*** ActionView::Template::Error Exception: Missing partial items/_fields with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :haml]}. Searched in:
  * "/my/path/to/application/app/views"
  * "/my/path/to/rvm/gems/ruby-2.1.5/gems/kaminari-0.16.3/app/views"
  * "/my/path/to/rvm/gems/ruby-2.1.5/gems/devise-3.5.4/app/views" 

Да, частичный файл существует в /my/path/to/application/app/views/items/_fields.html.haml

Кикер - это то, что иногда проходит тест, иначе он будет терпеть неудачу. Я бегу на машине Red Hat 5.

Итак, чтобы отладить это, я решил бросить begin/rescue.

.fields
  - begin
    = render partial: 'items/fields', locals: {f: f}
  - rescue Exception => e
    = byebug

  - if f.can_modify?(:object_a)
    = render partial: 'layouts/object_a_field', locals: {f: f, field: :object_a}
   - else
    .field#object_a
      = render partial: 'layouts/attribute', locals: {label: 'Object A', value: f.object.object_a_id ? f.object.object_a_number : 'Not Assigned'}

    .field#name
    - if f.can_modify?(:name)
      = f.label :name
      = f.text_field :name, {class: 'inputbox large_field', readonly: f.cannot_modify?(:name)}
      .smltxt (short description of the item)
    - else
      = render partial: 'layouts/attribute', object: f.object, locals: {field: :name}

Для любопытных, что в частичном items/fields:

.field
  - if f.can_modify?(:name)
    = f.label :name, 'Item'
    = f.text_field :name, {class: 'inputbox uppercase', maxlength: 16, readonly: !f.object.identifier.new_record?}
    .smltxt (character identifier)
  - else
    = render partial: 'layouts/attribute', object: f.object, locals: {field: :name, label: 'Item'}

Когда он проходит, я, очевидно, не ударяю байбуга, но когда он терпит неудачу, я делаю! Это позволяет мне играть с ним в среде типа Rails Console.

Поэтому я решил запустить эту специальную команду:

(byebug) render partial: 'items/fields', locals: {f: f}

И я получаю:

*** ActionView::Template::Error Exception: Missing partial items/_fields with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :haml]}. Searched in:
  * "/my/path/to/application/app/views"
  * "/my/path/to/rvm/gems/ruby-2.1.5/gems/kaminari-0.16.3/app/views"
  * "/my/path/to/rvm/gems/ruby-2.1.5/gems/devise-3.5.4/app/views" 

Итак, я думал, что удалю локальных жителей, чтобы увидеть, что-то изменилось:

(byebug) render partial: 'items/fields'

И я получаю:

*** ActionView::Template::Error Exception: undefined local variable or method `f' for #<#<Class:0x0000002a907610>:0x00000027beae48>

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

Обновление 1

Я добавил остальную часть представления, которая для ясности вызывает частичное выше.

В попытке устранить неполадки я также взял содержимое items/_fields.html.haml и поместил его там, где у меня был render partial: 'items/fields', locals: {f: f}..., тогда тест прошел, что означает, что другие частичные файлы в файле не имели выпуск. Таким образом, похоже, что это не может быть связано с содержимым файла.

Обновление 2

Кажется, добавив тег @javascript к нашей самой первой функции Cucumber, эта проблема часто устраняется. Каким-то образом браузер, загруженный перед другими тестами, улучшает шансы на его передачу. Не имеет смысла для меня, может быть, у кого-то есть идея об этом?

Обновление 3

Сегодня было обнаружено, что ошибка вообще не связана с огурцом. Такая же ошибка была обнаружена в производстве. Веб-интерфейс показал недостающую частичную ошибку, но для файла, который действительно существует. После перезапуска сервера Passenger с помощью touch tmp/restart.txt и затем ошибка исчезла. Так что он все еще очень прерывистый.

Обновление 4

Я добавил содержимое части, которое, кажется, случайно отсутствует.

Как мне узнать, почему Rails не может найти частичное, что на самом деле есть?

4b9b3361

Ответ 1

Я твердо верю, что обновление до Ruby 2.3.1 решило это для нас. Я не уверен, что могло измениться. Когда мы расследовали это, мой коллега и я подумали, что нашли строку в исходном коде Rails, которая частично обрабатывала частичные данные на основе версии Ruby.

У меня возникли проблемы с поиском этого сейчас, но я все еще хотел опубликовать, что проблемы, похоже, исчезли с тех пор, как мы перешли на новый Ruby.

Ответ 2

Эта ошибка обычно возникает, когда формат запроса отличается, и нет шаблона, который может ответить на него, пример format.js, format.html и т.д. Запрос будет работать, только если шаблон items/_fields.html.haml - это только быть правильным, если формат запроса - html

Я думаю, вы можете переименовать свой файл в items/_fields.haml, если хотите использовать для ответа на него любой формат запроса.

Ответ 3

Я думаю, вы могли бы попробовать указать формат и обработчик частичного рендеринга:

= render(
  partial: 'items/fields',
  formats:  [:html],
  handlers: [:haml],
  locals: {f: f}
)

Ответ 4

У меня была аналогичная проблема, но с другим камнем для рулей. Обычно это из-за кеширования.

Попробуйте установить настройку огурца

ActionView::Base.cache_template_loading = false

Если это работает, вы DO имеете проблему кеширования, которая будет возникать при производстве.

В режиме dev есть открытая проблема для кэширования: https://github.com/indirect/haml-rails/search?utf8=%E2%9C%93&q=cache_template_loading

Ответ 5

Наиболее распространенными типами контента в Rails являются :js, :json и :html. Если вы используете Rails UJS, вы можете указать тип содержимого в ссылках или элементах формы. Пример будет выглядеть следующим образом:

<%= form_for @task, remote: true, data: {'type' => :json} %>
  ...

В нашем контроллере мы ответим соответствующим образом:

def create
  respond_to do |format|
    format.json { render json: { status: 200, html: render_to_string(partial: 'form') }.to_json }
  end
end

Теперь, если ваша частная форма выглядит следующим образом:

tasks/_form.html.erb

Rails приведет к созданию ActionView:: Template:: Error Exception: Отсутствует частичное. Вы указали тип контента как json, поэтому он искал:

tasks/_form.json.erb

Теперь, если вы изменили форму на:

<%= form_for @task, remote: true, data: {'type' => :html} %>
  ...

И контроллер вроде этого:

def create
  respond_to do |format|
    format.html { render text: { status: 200, html: render_to_string(partial: 'form') } }
  end
end

Вы даже можете отобразить json в html-типе ответа типа контента:

def create
  respond_to do |format|
    format.html { render json: { status: 200, html: render_to_string(partial: 'form') }.to_json }
  end
end

А затем в javascript:

JSON.parse(data);

Вышеупомянутый scenerio будет работать нормально, потому что он будет искать расширение html файла в вызове render. Это важная часть. Призыв к рендерингу вызывает ошибку. Когда вы используете рендер, вы должны убедиться, что у вас есть шаблон или частичный, который соответствует типу содержимого.

Одним из решений, упомянутых выше, является удаление расширения. Но если вы не отвечаете на несколько форматов, это кажется немного излишним. Мое рекомендуемое решение - посмотреть, что сообщение об ошибке говорит вам, что оно ожидает. В вашем случае он ожидал html:

:formats=>[:html]