Rails - 在视图中渲染视图 - 传递参数

Rails - render a view in a view - pass params

在我的应用程序中,我可以使用以下方式调用视图 ('edit.html.erb'):

<%= link_to( tag.content, [object, tag], method: :patch) %>

如果我想在其他视图中呈现它,等效项是什么?

我如何将参数传递给它?

编辑

实际上我有一个父视图,我想在其中列出子项 (editable)。这些我也可以单独编辑。简单的解决方案是我创建一个 _partial,我从父视图以及 edit.html.erb.

渲染它

我可以使用 link:

调用此 edit.html.erb(或更新)
<%= link_to( tag.content, [object, tag], method: :patch) %>

这行得通。现在的问题是如何使用 render 渲染那个部分(让我们称之为 _update.html.erb)?仍然需要传递父(即对象)和子(标签)参数。我该如何使用 <% render partial "tags/update" PARAMS %>?

编辑完整示例

我想要实现的目标(简而言之)- 允许在注释视图(父级)中编辑标签(子级)。

对于模型/对象的现有记录 "Annotation",我想为附加的 PDF 添加标签。我在一个名为 "Annotate" 的 page/view 中执行此操作,我从 Annotation 编辑视图(使用 'link_to')打开它。此 "Annotate" 页面有 2 列(见下面的屏幕截图):

  1. 左窗格:2 个部分 - 1 个用于快速添加标签,- 2 个用于编辑现有标签(在 table 中列出)
  2. 右窗格:PDF

Tags和Annotation存在多态关系(按此设置

_form.html.erb 注释

<div class="row">
  <div class="col-md-6">
  <%= simple_form_for @annotation,  html: { class: 'form-horizontal', multipart: true },
    wrapper: :horizontal_form,
    wrapper_mappings: {
        check_boxes: :horizontal_radio_and_checkboxes,
        radio_buttons: :horizontal_radio_and_checkboxes,
        file: :horizontal_file_input,
        boolean: :horizontal_boolean
    } do |f| %>

    <div class="btn-toolbar btn-group", role="toolbar">
      <%= f.button :submit, 'Save', :class => "btn btn-xs btn-default" %> <%= link_to 'List' , annotations_path, :class => "btn btn-xs btn-default" %> <% unless @annotation.file.blank? %>
    <%= link_to 'Annotate', annotate_path(@annotation), :class => "btn btn-xs btn-default" %>
    <% end -%>
    </div>

    <h4>Annotation</h4>

    <%= f.error_notification %>

    <% if @annotation.file.blank? %>
      <%= f.input :file, as: :file, input_html: { accept: ('application/pdf') } %>
      <% else %>
    <% end -%>

    <%= f.input :name, placeholder: 'Enter name' %>

    <%= f.input :description, placeholder: 'Description', :input_html => { :rows => 3 } %>

    <%= f.association :documenttype, :collection => Documenttype.active.order(:name), prompt: 'Select document type' %>

    <%= f.association :sender, label: 'Submitted by' , prompt: 'Select sender' %>

    <%= f.association :receiver, label: 'Specific to', prompt: 'Select recipient' %>

    <%= f.input :active, as: :boolean %>

<% end -%>
  </div>

    <% unless @annotation.file.blank? %>
        <div class="col-md-6">
          <%= content_tag :iframe, nil, src: pdf_annotation_path(@annotation), width: "100%", height: "770px", frameBorder: "0" %>
        </div>
      <% end %>
    </div>
    <% unless @annotation.new_record? %>
      <div class="row">
        <hr>
          <div class="col-md-6">
            <%= render @annotation.comments %>
          </div>

          <div class="col-md-6">
            <%= render 'comments/form', :object => @annotation %>
          </div>
      </div>
    <% end -%>

注释视图 annotate.html.erb

<div class="row">
    <div class="col-lg-5">
        <div class="btn-toolbar btn-group" role="toolbar">
            <%= link_to 'Close', annotation_path(@annotation), :class => "btn btn-xs btn-default" %> <%= link_to 'List' , annotations_path, :class => "btn btn-xs btn-default" %>
        </div>
        <h4>Annotate document</h4>
        <div data-spy="affix">
                <%= render 'tags/form', :object => @annotation %>
                <br>
            <div class="panel panel-default" id="annotationResults">
                <%= render 'tags/tag_list', :object => @annotation %>
            </div>
        </div>
    </div>

    <div class="col-lg-7" id="file">
        <%= content_tag :iframe, nil, src: pdf_annotation_path(@annotation), width: "100%", height: "875px", frameBorder: "0" %>
    </div>

</div>

标签列表 _tag_list.html.erb

<table id="tags" class="table table-hover" style="background-color: white; word-wrap: break-word; font-size: 0.9em;" >
    <thead>
        <tr>
            <th>Tagged content</th>
            <th>as</th>
            <th>in</th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        <% object.tags.each do |tag| %>
            <% unless tag.content.blank? %>
            <tr data-tag-id='<%= tag.id %>', class='show-tag'>
                <td style="word-wrap: break-word;"><%= link_to( tag.content, [object, tag], method: :patch) %>
                <td><%= tag.tagtype.name %></td>
                <td><%= tag.tagtype.typeoftag %></td>
                <td><%= link_to '', [object, tag], method: :delete, data: { confirm: 'Please confirm!' }, :class => "glyphicon glyphicon-trash" %></td>
            </tr>
            <tr data-tag-id='<%= tag.id %>', class='edit-tag'>
                <td colspan="4"><%= render partial: 'shared/tester' %><%#= render partial: 'tags/update', object: @tag.tagable, tag: @tag %></td>
            </tr>
            <% end -%>
        <% end -%>
    </tbody>
</table>

标签更新形式 _update.html.erb

<%= simple_form_for [object, tag], html: { class: 'form-horizontal', multipart: true },
    wrapper: :horizontal_form,
    wrapper_mappings: {
        check_boxes: :horizontal_radio_and_checkboxes,
        radio_buttons: :horizontal_radio_and_checkboxes,
        boolean: :horizontal_boolean
      } do |f| %>

  <div class="btn-toolbar btn-group" role="toolbar">
    <%= f.button :submit, 'Save', :class => "btn btn-xs btn-default" %>
  </div>

    <%= f.error_notification %>

  tag id = <%= @tag.id %>

    <%= f.input :content, placeholder: 'Tagged content'%>

    <%= f.association :tagtype, prompt: 'Select tag type', :collection => Tagtype.active.order(:name).where(:documenttype => @tag.tagable.documenttype_id) %>

    <%= f.input :location, prompt: 'add as: x1, y1, x2, y2' %>

<% end -%>

路线

Rails.application.routes.draw do
  root 'dashboard#index'
  devise_for :users

  concern :tagable do
    resources :tags, only: [:new, :index, :create, :edit, :update]
  end

  resources :users, :documenttypes, :tagtypes, :business_partners
  resources :tags, only: [:show, :edit, :destroy, :index]

  resources :documents do
    resources :comments
    resources :tags, concerns: :tagable
    get "pdf", on: :member 
  end

  resources :annotations do
    resources :comments
    resources :tags
    get "pdf", on: :member

end

get "annotations/:id/annotate" => "annotations#annotate", as: 'annotate'

标签控制器

class TagsController < ApplicationController

    def index
    @tags = Tag.all.order(:tagable)
    end

  def show
    tagable = detect_tagable
    @tag = tagable.tags.find(params[:id])
  end

  def edit
    tagable = detect_tagable
    @tag = tagable.tags.find(params[:id])
    @tag.update(tag_params)
  end

  def create
    tagable = detect_tagable
    tagable.tags.create(tag_params)
    redirect_to tagable_path(tagable)
  end

  def update
    tagable = detect_tagable
    @tag = tagable.tags.find(params[:id])
    render 'edit'
#    @tag.save
    @tag.update(tag_params)
  end

  def destroy
    tagable = detect_tagable
    @tag = tagable.tags.find(params[:id])
    @tag.destroy
    redirect_to tagable_path(tagable)
  end

  private

    def tagable_path(tagable)
      case tagable
      when Document
        document_path(tagable)
      when Annotation
        annotate_path(tagable)
      else
        fail 'Unknown tagable'
      end
    end

    def detect_tagable
      if params[:annotation_id]
        Annotation.find(params[:annotation_id])
      elsif params[:document_id]
        Document.find(params[:document_id])
      else
        fail 'Tagable not found'
      end
    end

    def tag_params
      params.require(:tag).permit(:content, :location, :tagtype_id, annotation_attributes: { annotation_ids:[] }, document_attributes: { document_ids:[] })
    end

end

这就是我所做的-如果Rails中有更好的方法(我可以想象)那么我更愿意学习。

这里采用的方法应该是使用嵌套形式,accepts_nested_attributes_forallow_destroy: truereject_if 用于验证。

  • 要销毁嵌套记录,请使用 accepts_nested_attributes_for :tags, allow_destroy: true 并确保(除了 :id)还 :_destroy 添加到 strongparams
  • 要对嵌套字段使用验证,请使用 accepts_nested_attributes_for :tags, allow_destroy: true, reject_if: :something_to_check