#ruby-on-rails-3
#ruby-on-rails-3
Вопрос:
Это странное требование, для которого может потребоваться другой подход, но мой мозг застрял.
Я хочу выполнить что-то вроде этого:
class UsersController < ApplicationController
before_filter Proc.new { share_params :user_name }, :only => :show
render_djs
end
class ApplicationController < ActionController::Base
include ActionView::Helpers::CaptureHelper
def share_params(*shared)
content_for(:djs) { shared.inspect }
end
def self.render_djs
before_filter Proc.new {
render :inline => "<%= yield(:djs) %>" if request.format.djs?
}
end
end
Я хочу использовать, content_for
потому что я могу захотеть добавить содержимое в :djs
результат в других фильтрах.
Однако этот код вызывает undefined method output_buffer=
.
Полагаю, я мог бы использовать переменную экземпляра, но это кажется более чистым, не так ли?
Комментарии:
1. Для будущих читателей обратитесь к ответу @Camden, используя переменную экземпляра, переданную в представление. Контроллеры не должны знать, что вы хотите сделать со своей информацией, а просто передавать ее в представление (и
content_for()
это функция представления). Это не зря называется «Model-View-Controller».
Ответ №1:
Вам нужно использовать #view_context
метод для доступа к контексту представления, а затем вы можете делать то же самое, что и в представлении:
view_context.content_for(:something, view_context.render(partial: 'some_partial'))
Комментарии:
1. … по-видимому, ни в Rails 5.
2. @CyrilDuchon-Дорис Кристиан Привет, ребята, смотрите мой ответ выше.
Ответ №2:
вы не можете использовать content_for
в контроллерах, даже если вы знали, что view_context
можете предоставить метод. смотрите проблему здесь:https://github.com/rails/rails/issues/4906
метод view_context
всегда возвращает новый объект. при вызове view_context.content_for(:somethin, 'content')
он сохранит содержимое в переменной экземпляра нового объекта.
вы можете провести эксперимент в контроллерах, подобных следующему:
view_context.content_for(:title, 'hello')
view_context.view_flow.content # => {}
a = view_context
a.content_for(:title, 'hello')
a.view_flow.content # => {:title=>"hello"}
в любом случае, если вы все еще хотите использовать content_for
в контроллерах, вы можете переопределить view_context
в контроллерах в качестве обходного пути. но я не знаю, есть ли какие-либо побочные эффекты.
def view_context
@_view_context ||= super
end
Комментарии:
1. Пока что обходной путь в Rails 7.0.3 выглядит нормально. Я собираюсь использовать это и обновлю, если обнаружу скрытую ошибку (например, с turbo …)
Ответ №3:
Я нашел это очень полезным в случае настройки заголовка для моей страницы.
Я могу просто установить content_for из контроллера
class PostsController < ApplicationController
def index
content_for :title, "List of posts"
...
end
end
https://gist.github.com/hiroshi/985457
https://github.com/clmntlxndr/content_for_in_controllers
Комментарии:
1. Пробую это в данный момент и, по крайней мере, на Rails 3.2, это не работает. content_for(:title) из представления работает, но из контроллера, похоже, уходит в черную дыру.
2. вы пытались добавить этот драгоценный камень? github.com/clmntlxndr/content_for_in_controllers
3. Я не добавлял сам gem, но я взял его код, чтобы посмотреть, работает ли он. Похоже, что Rails начал стирать контекст представления между вызываемым контроллером и отображаемым шаблоном, поэтому контекстный массив, который вы задаете из контроллера, не используется из представления. В любом случае, я закончил тем, что использовал что-то намного более простое, установив @title из контроллера, а затем попросил view выполнить content_for.
4. Большое вам спасибо за публикацию этого! Я смог использовать это решение для переопределения заголовков моих страниц. Приветствия.
Ответ №4:
Если, как и я, вы просто хотите задать содержимое в контроллере в виде заголовка, то, вероятно, лучше просто использовать переменную, которая автоматически передается представлениям и помощникам. например.
контроллер:
class AController < ApplicationController
before_action :set_title
private
def set_title
@title = 'Email Subscription'
end
end
и помощник:
module ApplicationHelper
def title_suffix
" - #{@title}" unless @title.nil?
end
end
и шаблон:
<!DOCTYPE html>
<html>
<head>
<title>Standard Title<%= title_suffix %></title>
...
Ответ №5:
Я нашел более чистый способ, чем установка content_for из контроллера.
В моем случае у меня есть боковая панель, которая должна отображаться для каждого просмотра.
В моем макете у меня есть
<%= yield :sidebar %>
Тогда у меня есть частичное вызываемое _set_sidebar.html.erb
, которое делает это
<% content for :sidebar do %>
<% render :partial => "layouts/sidebar", locals => {:locs => locs} %>
<% end %>
Затем я просто добавляю однострочную строку в каждое представление, в котором я хочу также иметь эту боковую панель
<%= render :partial => "layouts/set_sidebar", locals => {:locs => locs}
В противном случае я ранее использовал это
https://gist.github.com/985457 с .html_safe, когда я использовал render_to_string
Комментарии:
1. «Затем я просто добавляю однострочную строку в каждое представление, в котором я хочу также иметь эту боковую панель», Для этого и существуют макеты (для будущих читателей).
Ответ №6:
view_context
не сработало в 5.1.4
render inline: erb
однако, сделал:
render inline: <<~ERB, layout: 'layout_expecting_subtabs'
<% content_for(:subtabs, render(partial: 'somewhere/subtabs') ) %>
<h1> yielded content </h1>
ERB