简体   繁体   中英

Store data from one table to another in rails

I have a fundings table and organisations table. Fundings table has organisation_id. In fundings table I have fields that are same with organisations table. What I want is when application is created and on funding show page there is a add button to add all fields that are same in fundings and organisations table gets stored in organisations table as well. Please help

_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(funding show page)

<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 %>

if admin clicks on add organisation fields get added to organisation table.

schema funding table

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

schema organisations table

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

funding.rb

belongs_to :organisation

organisation.rb

has_many :fundings

organisations controller I have a new and create method to create organisation by the admin directly.so i have added a new_org method to get add the organisation from the funding table. But I am not able to find out how to implement it.

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

Something like this should work:

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 %>

Alternatively you can update all double fields (without whitelisting) using the following code:

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

However keep in mind that this may produce unwanted results. For example some fields you don't want to update like 'id' , 'created_at' , 'updated_at' are most likely present on both instances, and maybe some custom double fields.

This can be resolved by creating a blacklist to exclude those fields:

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))

But generally speaking it's better to whitelist.

This is not a good way to do it but you can define a hidden form with hidden fields with values of @funding.x on show page by defining @organization = Organization.new in show method on Fundings.controller then you can simply post it as normal form. Or you can show this form to only admins.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM