【问题标题】:Store data from one table to another in rails在 Rails 中将数据从一个表存储到另一个表
【发布时间】:2018-07-20 02:06:56
【问题描述】:

我有一个资金表和组织表。 Fundings 表有 organization_id。在资金表中,我有与组织表相同的字段。我想要的是当创建应用程序并且在资金显示页面上有一个添加按钮来添加资金中相同的所有字段,并且组织表也存储在组织表中。请帮忙

_form.html.erb (funding_form)

<%= form_for([@parent, @child, @funding], :html => {class: "form-horizontal",role: "form"}) do |form| %>
      <div class = "form-group">
        <div class="control-label col-sm-2">
          <%= form.label :activity_details, class: "required" %>
        </div>
        <div class="col-sm-8">
          <%= form.text_area :activity_details, required: true %>
        </div>
      </div>

<!--Adding organisation -->
      <div class = "form-group">
        <div class="control-label col-sm-2">
          <%= form.label :name_of_organisation, id: "name_of_organisation-label" %>
        </div>
      <div class="col-sm-8">
        <%= form.text_field :name_of_organisation, class: "form-control hidden", id: "name_of_organisation-textfield" %>
      </div>
    </div>

    <div class = "form-group">
        <div class="control-label col-sm-2">
          <%= form.label :address, id: "address-label" %>
        </div>
      <div class="col-sm-8">
        <%= form.text_field :address, class: "form-control hidden", id: "address-textfield" %>
      </div>
    </div>
    <div class = "form-group">
        <div class="control-label col-sm-2">
          <%= form.label :city, id: "city-label" %>
        </div>
      <div class="col-sm-8">
        <%= form.text_field :city, class: "form-control hidden", id: "city-textfield" %>
      </div>
    </div>
    <div class = "form-group">
        <div class="control-label col-sm-2">
          <%= form.label :province, id: "province-label" %>
        </div>
      <div class="col-sm-8">
        <%= form.text_field :province, class: "form-control hidden", id: "province-textfield" %>
      </div>
    </div>


<!-- End Adding organisation -->        


      <div class="form-group">
        <div class="col-sm-10">
          <%= form.submit "Apply", class: 'btn btn-primary btn-lg' %>
        </div>
      </div>
    </div>
  </div>
<% end %>

show.html.erb(资金展示页面)

<p>
  <strong>Name of Organisation:</strong>
<%= @funding.name_of_organisation %></p><br>
<p>
  <strong>Address:</strong>
<%= @funding.address %></p><br>
<p>
  <strong>City:</strong>
<%= @funding.city %></p><br>
<p>
  <strong>Province:</strong>
<%= @funding.province %></p><br>
<p>

<% if current_user.admin? %>
        <%= link_to 'Add Organisation', "" %>
<% end %>

如果管理员点击添加组织字段被添加到组织表中。

模式资金表

t.text "activity_details"
t.string "city"
t.string "name_of_organisation"
t.string "province"
t.text "address"

架构组织表

t.string "name_of_organisation"
t.text "address"
t.string "city"
t.string "province"

funding.rb

belongs_to :organisation

组织.rb

has_many :fundings

组织控制器 我有一个新的 create 方法可以由管理员直接创建组织。所以我添加了一个 new_org 方法来从资金表中添加组织。但我不知道如何实现它。

def new_org
    @organisation = Organisation.new
end

def create_org
    @organisation = Organisation.new(organisation_params)
    if @organisation.save
        flash[:success] = "Organisation is added"
        redirect_to main_admin_service_provider_path
    else 
        render 'new'
    end
end

【问题讨论】:

  • 请提供您尝试实现该控制器的代码。为什么需要一些数据的副本?
  • @Leo 我需要复制它,因为我不希望普通用户直接将组织添加到组织表中。

标签: ruby-on-rails ruby ruby-on-rails-5


【解决方案1】:

这样的事情应该可以工作:

app/controllers/fundings_controller.rb

class FundingsController < ApplicationController

  before_action :set_funding, on: %i[show add_organisation]

  # ...

  def update_organisation
    return head :forbidden unless current_user.admin?

    # assuming funding always has an organisation
    whitelist = %w[your field names]
    @funding.organisation.update!(@funding.attributes.slice(*whitelist))
    redirect_to @funding, notice: 'fields successfully added to organisation'
  end

  # ...

  private

  def set_funding
    @funding = Funding.find(params[:id])
  end

end

config/routes.rb

Rails.application.routes.draw do

  # ...

  resources :fundings, only: :show do

    # using patch because we are updating an existing resource
    # but you can change this to whatever you like
    patch 'update_organisation', on: :member

  end

  # ...

end

app/views/fundings/show.html.erb

<% if current_user.admin? %>
   <%= link_to 'Add Organisation', update_organisation_funding_path(@funding), method: :patch %>
<% end %>

或者,您可以使用以下代码更新所有双字段(不列入白名单):

double_attribute_names = @funding.attribute_names & @funding.organisation.attribute_names
@funding.organisation.update!(@funding.attributes.slice(*double_attribute_names)

但是请记住,这可能会产生不需要的结果。例如,您不想更新的某些字段(如 'id''created_at''updated_at')很可能出现在两个实例上,并且可能存在一些自定义双字段。

这可以通过创建一个黑名单来排除这些字段来解决:

blacklist = %w[id created_at updated_at]
double_attribute_names = @funding.attribute_names & @funding.organisation.attribute_names
@funding.organisation.update!(@funding.attributes.slice(*double_attribute_names).except(*blacklist))

但一般来说还是白名单比较好。

【讨论】:

  • 您可能也不想处理错误。我使用了update!,如果记录无效或无法保存到数据库,则会引发异常。导致生产中出现 500 页,开发模式下出现错误屏幕。
【解决方案2】:

这不是一个好方法,但您可以通过定义在显示页面上定义具有隐藏字段的隐藏表单,其值为@funding.x @organization = Organization.newFundings.controller 的 show 方法中,然后您可以简单地将其作为正常形式发布。或者,您可以仅向管理员显示此表单。

【讨论】:

  • 表单的发布操作将如何工作。如何在资金控制器中定义?
  • ` ... ` 实际上你不需要定义@organization 你可以使用form_for(:organization, url: .....)。搜索路径以在您的路线中创建组织,并使用 method: :post 参数将其放入您的表单中。
  • { multipart: true, class: "form-horizo​​ntal", role: "form"}) 做 |f| %>
    我试过这个。这是我得到未定义方法“hidden_​​field_tag”的错误
  • &lt;%= f.hidden_field :user_id, { :value =&gt; user.id } %&gt; 你可以像这样在输入上设置一些值。
  • 当我点击提交时,我得到了错误。没有路线匹配 [PATCH] "/organisations"
猜你喜欢
  • 2010-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多