【问题标题】:How render a view template from another controller and pass is a local variable?如何从另一个控制器渲染视图模板并传递一个局部变量?
【发布时间】:2015-09-27 21:17:58
【问题描述】:

在 Ruby on Rails 中,如何从另一个控制器的命名空间渲染部分内容并将对象作为局部变量传递?

例如,在views/posts 目录(由PostsController 管理)中的视图模板中,我需要渲染views/polls 目录中的一部分。

我尝试了以下方法:

.item_index  
  = f.fields_for :poll_items do |poll|
    = render :partial => 'polls/poll_item_fields', f: poll
  .links
    = link_to_add_association 'Add more', f, :poll_items, render_options: {class: 'links'}

我有错误:

Showing /home/ubuntu/workspace/app/views/polls/_poll_item_fields.html.haml where line #3 raised:
undefined local variable or method `f' for #<#<Class:0x0000000c01ec38>:0x0000000f56b170>**

编辑

所有完整视图:

posts/new.html.haml

%h1= title "New post"
= simple_form_for [@group, @post] do |f|
  = f.error_messages header_message: nil
  = render 'form', f: f

  .form-actions
    %p= attach_links
    = f.button :submit, 'Опубликовать пост', class: 'btn-bg'
    - if paid?
      = f.button :submit, 'сохранить черновик', class: 'btn-inverse', name: 'draft'
    = button_tag 'Добавить опрос', type: 'button', id: 'poll-btn', class: 'btn btn-bg'
    %p
      Вернуться в группу:
      = link_to @group, @group

posts/_form.html.haml

- cat = Post::CATEGORIES.map { |c| [t(c, scope: :post_categories), c] }
= f.input :category, collection: cat
= f.input :subject, input_html: { class: 'input-block-level' }
= f.input :body, input_html: { rows: 5, class: 'ctrlenter input-block-level expanding' }
= link_to "#", class: 'smiley', role: 'add_smiley', tabidex: 4 do
  %i.icon.icon-smile
  смайлы
= smiles_helper '#post_body'

.form-horizontal
  = f.input :tag_list, input_html: { class: 'input-block-level' }
  - if (current_user.paid? && current_user.moderated_group_ids.include?(@group.id)) || moderator?
    = f.input :comments_disabled, inline_label: true, label: false
.attachments
  = f.simple_fields_for :attachments do |af|
    = render "attachments/#{af.object.asset_type.underscore}", :f => af
.poll{style: "display: none;"}
  %h1 "Новый опрос"
  = f.simple_fields_for :poll do |poll|
    = render "polls/poll_fields", f: poll

民意调查/_poll_fields.html.haml

= f.error_messages header_message: nil
= f.input :question, input_html: { class: 'input-block-level' }
= f.input :results_hidden, as: :boolean, inline_label: 'Скрыть результаты до окончания опроса', label: false
= f.input :from_date, as: :datetime, input_html: { class: 'poll_date' }
= f.input :to_date, as: :datetime, input_html: { class: 'poll_date' }
%h3#poll-items Варианты ответа (не больше пяти)
.item_index  
  = f.fields_for :poll_items do |poll_item|
    = render partial: 'polls/poll_item_fields', locals: {f: poll_item}
  .links
    = link_to_add_association 'Добавить еще вариант', f, :poll_items, render_options: {class: 'links'}

民意调查/poll_items_fields

.poll_row
  .poll_item
    = f.input :answer, input_html: { class: 'ctrlenter expanding' }, label: false, placeholder: 'Введите вариант ответа'
    = link_to_remove_association "удалить", f, { wrapper_class: 'poll_item' }

使用= render partial: 'polls/poll_item_fields', locals: { f: poll } 时,显示错误:howing /home/ubuntu/workspace/app/views/polls/_poll_fields.html.haml 其中第 11 行出现:howing /home/ubuntu/workspace/app/ views/polls/_poll_fields.html.haml 第 11 行提出: 缺少部分帖子/poll_item_fields

第 11 行是= link_to_add_association 'Add more', f, :poll_items, render_options: {class: 'links'}

【问题讨论】:

    标签: ruby-on-rails haml


    【解决方案1】:

    通过render 将变量传递给部分时,您需要将它们包装在locals 键中:

    = render partial: 'polls/poll_item_fields', locals: { f: poll }
    

    更多详情,请参阅Layouts and Rendering guide

    【讨论】:

    • 我试过了。显示错误:缺少部分帖子/poll_item_fields
    • 但它并没有抱怨没有locals 键的部分丢失?
    • 不,它没有抱怨没有 locals 键的丢失部分。
    • 当使用 = 渲染部分:'polls/poll_item_fields',本地:{ f: poll },显示错误:howing /home/ubuntu/workspace/app/views/polls/_poll_fields。 html.haml 其中第 11 行提出:缺少部分帖子/poll_item_fields 第 11 行是 = link_to_add_association 'Add more', f, :poll_items, render_options: {class: 'links'}
    【解决方案2】:

    render 方法有两种形式,可让您以不同的方式传递本地变量。

    快捷方式版本将接受Hash:

    = render 'polls/poll_item_fields', f: poll
    

    但是,您使用的是 long 版本。如果你使用partial键,那么你还需要使用locals键:

    = render partial: 'polls/poll_item_fields', locals: { f: poll }
    

    这不仅仅是风格问题,而是因为 ruby​​ 如何处理方法参数。

    快捷方式版本中,第一个参数是String,第二个参数是Hash。 Rails 会知道 Hash 将包含本地变量。
    然而,在第二个版本中,第一个(也是唯一的)参数是Hash。如果没有 :locals 键,并且由于 Ruby 允许省略括号和花括号的语法,它将被转换为:

    render({ partial: 'polls/poll_item_fields', f: poll })
    

    这会让 Rails 有点困惑,因为它无法将本地变量与传递给该方法的其他键控选项隔离开来。

    最后还是风格问题:方法签名就是这样设计的。我希望我的解释能让事情更清楚一点!

    【讨论】:

    • 感谢您的回复,但我该如何解决我的错误?它的问题是因为与其他本地密钥 f 冲突?
    • 当使用 = 渲染部分:'polls/poll_item_fields',本地:{ f: poll },显示错误:howing /home/ubuntu/workspace/app/views/polls/_poll_fields。 html.haml 其中第 11 行提出:缺少部分帖子/poll_item_fields 第 11 行是 = link_to_add_association 'Add more', f, :poll_items, render_options: {class: 'links'}
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-28
    • 1970-01-01
    • 2013-06-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多