ruby-on-rails 如何将我的模型参数传递给视图Rails?

yduiuuwa  于 2023-02-01  发布在  Ruby
关注(0)|答案(4)|浏览(184)

我正在尝试使用prawn gem在Rails中生成pdf文件。pdf文件的数据部分是硬编码的,但其中一些应该来自Rails表单。
我已经生成了一个包含名称、地址和ID的"模板"支架。使用Prawn,我已经创建了一个pdf文件。它可以打印出一个pdf文件,没有任何问题。我想将模型参数内联传递到pdf中,这样我就可以编写:"此表单适用于居住在#{Template. address}且ID为#{Template. NationalId}的#{Template.name}",其中姓名、地址和NationalId来自表单。
我还想推广这种方法,并能够做到这一点,为不同的pdf报告,证书等来自同一应用程序。
我如何传递这些数据?
下面是我的代码:

#Controller
  class TemplatesController < ApplicationController
  before_action :set_template, only: %i[ show edit update destroy ]

def index
  @templates = Template.all

  respond_to do |format|
    format.html
    format.pdf do
      pdf = ReportPdf.new
      send_data pdf.render, filename: 'report.pdf', type: 'application/pdf', 
      disposition: "inline"
    end
  end
end

def create
@template = Template.new(template_params)

respond_to do |format|
  if @template.save
    format.html { redirect_to @template, notice: "Template was successfully created." }
    # format.pdf { render :index, status: :created, location: @template }
    format.json { render :index, status: :created, location: @template }
  else
    format.html { render :new, status: :unprocessable_entity }
    format.json { render json: @template.errors, status: :unprocessable_entity }
  end
end
end

#...lots of other controllers update, destroy etc

private
# Use callbacks to share common setup or constraints between actions.
def set_template
  @template = Template.find(params[:id])
end

# Only allow a list of trusted parameters through.
def template_params
  params.require(:template).permit(:name, :address, :NationalId)
end
end

My Report.pdf(将数据插入文本内容区域)

class ReportPdf < Prawn::Document
def initialize
    super()
    header
    text_content
end

def header
    #This inserts an image in the pdf file and sets the size of the image
    image "#{Rails.root}/app/assets/images/logo.jpg", width: 230, height: 75
  end

  def text_content
    # The cursor for inserting content starts on the top left of the page. Here we move it down a little to create more space between the text and the image inserted above
    y_position = cursor - 50

    # The bounding_box takes the x and y coordinates for positioning its content and some options to style it
    bounding_box([0, y_position], :width => 270, :height => 300) do
      text "**Pass params here**", size: 15, style: :bold
      text "Lorem ipsum dolor sit amet, consectetur adipiscing elit. ."
    end

    bounding_box([300, y_position], :width => 270, :height => 300) do
      text "Duis vel", size: 15, style: :bold
      text "Duis vel tortor elementum, ultrices tortor vel, accumsan dui. Nullam in dolor rutrum, gravida turpis eu, vestibulum lectus. Pellentesque aliquet dignissim justo ut fringilla. Interdum et malesuada fames ac ante ipsum primis in faucibus. Ut venenatis massa non eros venenatis aliquet. Suspendisse potenti. Mauris sed tincidunt mauris, et vulputate risus. Aliquam eget nibh at erat dignissim aliquam non et risus. Fusce mattis neque id diam pulvinar, fermentum luctus enim porttitor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos."
    end
    
    end

  end

表格

<%= form_with(model: template, local: true) do |form| %>
   <% if template.errors.any? %>
     <div id="error_explanation">
       <h2><%= pluralize(template.errors.count, "error") %> prohibited this template 
       from being saved:</h2>

       <ul>
         <% template.errors.full_messages.each do |message| %>
           <li><%= message %></li>
         <% end %>
       </ul>
    </div>
  <% end %>

  <div class="field">
    <%= form.label :address %>
    <%= form.text_field :address %>
  </div>

  <div class="field">
    <%= form.label :address %>
    <%= form.text_field :address %>
  </div>

  <div class="field">
    <%= form.label :NationalId %>
    <%= form.text_field :NationalId %>
  </div>

  <div class="actions">
    <%= form.submit %>
    </div>
  <% end %>
bpsygsoo

bpsygsoo1#

您可以将选项传递给初始化程序方法:

class ReportPdf < Prawn::Document
  attr_reader :template
  # You should keep the initialzer signature of the super method
  def initialize(templates:, **options, &block)
    @templates = templates
    # the super method still uses the old style initialize(options = {}, &block)
    # instead of keyword arguments
    super(options, &block) 
    header
    text_content
  end

  def text_content
  # The cursor for inserting content starts on the top left of the page. Here we move it down a little to create more space between the text and the image inserted above
    y_position = cursor - 50

    # The bounding_box takes the x and y coordinates for positioning its content and some options to style it
    bounding_box([0, y_position], :width => 270, :height => 300) do
      text "**Pass params here**", size: 15, style: :bold
      text "Lorem ipsum dolor sit amet, consectetur adipiscing elit. ."
    end

    templates.each do |template|
      bounding_box([300, y_position], :width => 270, :height => 300) do
        text "Duis vel", size: 15, style: :bold  
        # @todo NationalId should be named national_id 
        #  change the name of the column or setup an alias if you cannot
        text "This form is for #{template.name} who lives at #{template.address} 
        and has an id of #{template.NationalId}"
      end
    end
  end
end

这里我们使用了一个manditory关键字参数,你也可以使用一个位置参数或者使参数可选:

# postitional argument
def initialize(templates, **options, &block)

# optional keyword argument
def initialize(templates: [], **options, &block)

关键字参数的优点是显式性,并且您不必记住参数的顺序。

def index
  @templates = Template.all

  respond_to do |format|
    format.html
    format.pdf do
      pdf = ReportPdf.new(templates: @templates)
      send_data pdf.render, filename: 'report.pdf', type: 'application/pdf', 
      disposition: "inline"
    end
  end
end
up9lanfz

up9lanfz2#

当您使用ReportPdf类(使用pdf = ReportPdf.new)创建PDF时,您可以传入您想要的任何参数。您只需要将匹配的参数添加到ReportPdf类中的initialize方法。因此,例如:

pdf = ReportPdf.new(@name, @address)
def initialize(name, address)
  @name = name
  @address = address
  super
  header
  text_content
end

如果需要传入大量变量,则向ReportPdf类添加方法以接收这些变量可能会更简洁:

pdf = ReportPdf
  .new
  .name(@name)
  .address(@address)
  .salutation(@salutation)
  .something_else(@value)
  etc
mf98qq94

mf98qq943#

这看起来很接近。您是要打印索引页中的所有文档,还是只打印表单中提交的文档(从显示页打印最简单)。不要打印索引中的一个文档,而是通过显示页打印它

def show
  @template = Template.find(params[:id])

  respond_to do |format|
    format.html
    format.pdf do
      pdf = ReportPdf.new(template: @template)
      send_data pdf.render, filename: 'report.pdf', type: 'application/pdf', 
      disposition: "inline"
    end
  end
end

然后可以添加所需的模板参数

class ReportPdf < Prawn::Document
def initialize(template)
    @template = template
    super()
    header
    text_content
end

def header
    #This inserts an image in the pdf file and sets the size of the image
    image "#{Rails.root}/app/assets/images/logo.jpg", width: 230, height: 75
  end

  def text_content
    # The cursor for inserting content starts on the top left of the page. Here we move it down a little to create more space between the text and the image inserted above
    y_position = cursor - 50

    # The bounding_box takes the x and y coordinates for positioning its content and some options to style it
    bounding_box([0, y_position], :width => 270, :height => 300) do
      text "Name: #{@template.name}, Address: #{@template.address}, Ect...", size: 15, style: :bold
      text "Lorem ipsum dolor sit amet, consectetur adipiscing elit. ."
    end

    bounding_box([300, y_position], :width => 270, :height => 300) do
      text "Duis vel", size: 15, style: :bold
      text "Duis vel tortor elementum, ultrices tortor vel, accumsan dui. Nullam in dolor rutrum, gravida turpis eu, vestibulum lectus. Pellentesque aliquet dignissim justo ut fringilla. Interdum et malesuada fames ac ante ipsum primis in faucibus. Ut venenatis massa non eros venenatis aliquet. Suspendisse potenti. Mauris sed tincidunt mauris, et vulputate risus. Aliquam eget nibh at erat dignissim aliquam non et risus. Fusce mattis neque id diam pulvinar, fermentum luctus enim porttitor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos."
    end
    
    end

  end

然后,在显示视图中,您可以直接链接到它或创建一个按钮来链接到它

<%= link_to 'Download PDF', template_path(@template, format:"pdf"), class: "btn btn-primary" %>
8oomwypt

8oomwypt4#

在模型中使用示例变量。例如:

def text
  @user = User.all
end

因此,如果用户在控制器方法中定义@user,则@user将在视图中可用。
默认情况下,示例变量在整个请求周期中可用。

相关问题