簡體   English   中英

Ruby on Rails:通過表單將值插入db中的數組字段

[英]Ruby on Rails: Insert values via form into array field in db

您如何將表單中的值插入數據庫中的數組? 我使用的是簡單形式,rails 4.1,postgresql db。

這是我的表格,除了影響和可能性字段(兩個數組)之外,所有字段都正確更新。 它們是此問題的重點:

<%= simple_form_for(@risk) do |f| %>
  <%= render 'shared/error_messages', object: f.object %>
  <div class="form-group">
    <%= f.input :title, required: false, :error => false, input_html: { class: 'form-control' } %>
  </div>

  <div class="form-group">
    <%= f.input :description, required: false, :error => false,  as: :text, input_html: { class: 'form-control description' } %>
  </div>

  <div class="form-group">
    <%= f.input :area, :collection => ['Operations', 'IT', 'Finance'], required: false, :error => false, input_html: { class: 'form-control' } %>
  </div>

  <div class="form-group">
    <%= f.input :owner, :collection => User.all, required: false, :error => false, input_html: { class: 'form-control' } %>
  </div>

  <div class="form-group">
    <%= f.input :action, required: false, :error => false, input_html: { class: 'form-control' } %>
  </div>

  <div class="form-inline">
    <span class="date-of-action-input">
    <%= f.input :date_of_action, :as => :date, :start_year => Date.today.year - 10, :end_year => 2030,
        :order => [ :day, :month, :year], :required => false, :error => false, input_html: { class: 'form-control' } %>
    </span>
    <span class="action-completed-input">
    <%= f.input :action_completed, as: :boolean, required: false, :error => false, input_html: { class: 'form-control' } %>
    </span>

    <span class="impact-input">
    <%= f.input :impact, required: false, :error => false, input_html: { class: 'form-control' } %>
    </span>
    <span class="likelihood-input">
    <%= f.input :likelihood, required: false, :error => false, input_html: { class: 'form-control' } %>
    </span>
    <span class="submit-risk">
    <%= f.button :submit, :error => false, :error => false, input_html: { class: 'form-control' } %>
    </span>
  </div>
<% end %>

這里是關聯的控制器(risks_controller.rb):

class RisksController < ApplicationController
before_action :signed_in_user
before_action :correct_user, only: [:destroy, :update]


def create
    @risk = current_user.risks.build(risk_params)
    if @risk.save
      flash[:success] = "Risk created!"
      redirect_to root_url
    else
      render 'new'
    end
end

def new
  @risk = Risk.new
end

def destroy
  @risk.destroy
  redirect_to root_url
end

def edit
  @risk = Risk.find(params[:id])
end

def update
  @risk = Risk.find(params[:id])
    @risk.assign_attributes(risk_params)
    if @risk.changed? == false
      flash[:info] = "No changes were made"
      redirect_to root_url
    elsif @risk.update_attributes(risk_params)
      flash[:success] = "The risk has been updated."
      redirect_to root_url
    else
        render 'new'
    end
end

private

    def risk_params
        params.require(:risk).permit(:description, :title, :area, :owner, :action, :date_of_action, :action_completed, :impact, :likelihood)
    end

  def correct_user
    if current_user.admin?
      @risk = Risk.find_by(id: params[:id])
      redirect_to root_url if @risk.nil?
    else
      @risk = current_user.risks.find_by(id: params[:id])
      redirect_to root_url if @risk.nil?
    end
  end

end

我的數據庫架構文件:

ActiveRecord::Schema.define(version: 20140617165640) do

  create_table "risks", force: true do |t|
    t.integer  "user_id"
    t.string   "description"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.string   "title"
    t.string   "area"
    t.string   "owner"
    t.string   "action"
    t.date     "date_of_action"
    t.boolean  "action_completed", default: false
    t.integer  "impact",           default: [],    array: true
    t.integer  "likelihood",       default: [],    array: true
  end

  add_index "risks", ["user_id", "created_at"], name: "index_risks_on_user_id_and_created_at", using: :btree

  create_table "users", force: true do |t|
    t.string   "name"
    t.string   "email"
    t.boolean  "admin",           default: false
    t.datetime "created_at"
    t.datetime "updated_at"
    t.string   "password_digest"
    t.string   "remember_token"
  end

  add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree
  add_index "users", ["remember_token"], name: "index_users_on_remember_token", using: :btree

end

我以為代碼看起來像這樣,但是,a,我的第一個Rails項目和我需要一些指導。 在Risks_controller.rb中:

def create
  @risk = current_user.risks.build(risk_params)
  @impact = risk_params[:impact]
  @userid = current_user.id
  @impacttoupdate = Risk.select(:impact).where(id: risk_params[:id])
  @impacttoupdate.insert(@userid, @impact)
    if @risk.save
      flash[:success] = "Risk created!"
      redirect_to root_url
    else
      render 'new'
    end
end

我想根據用戶ID插入值。 因此,如果用戶ID為3,則他們提交的表單中的值應進入數組的第3個插槽。

您必須在強參數中定義發布值是數組。

def risk_params
    params.require(:risk).permit(:description, :title, :area, :owner, :action, :date_of_action, :action_completed, {:impact => []}, {:likelihood=>[]})
end

對於Seong和其他人-這是一些基本代碼,說明我是如何工作的。 這不是很優雅,那時候我還是Rails的新手。

def update
@risk = Risk.find(params[:id])
#1. capture the existing arrays from the db before anything 
#has happened to them
@impactarray = @risk.impact
@likelihoodarray = @risk.likelihood
#2. update ALL attributes, including impact and likelihood fields incorrectly
@risk.assign_attributes(risk_params)
if @risk.changed? == false
  flash[:info] = "No changes were made"
  redirect_to root_url
elsif @risk.update_attributes(risk_params)
  #3. delete the existing value in the array, even if it is nil
  @impactarray.delete_at(current_user.id)
  #4. repeat this for the likelihood field
  @likelihoodarray.delete_at(current_user.id)
  #5. capture the value that was entered, it would be the first 
  #and only value in the incorrectly formed array
  @impactscore = @risk.impact[0]
  #6. insert the new value correctly according to user id by inserting it 
  #back into the original arrays we captured at the start of the method
  @impactarray.insert(current_user.id, @impactscore)
  #7. do the same for the likelihood column
  @likelihoodscore = @risk.likelihood[0]
  @likelihoodarray.insert(current_user.id, @likelihoodscore)
  #8. officially make these changes on the @risk object and save them
  @risk.update_column("impact", @impactarray)
  @risk.update_column("likelihood", @likelihoodarray)
  #9. update the score columns to save computation on the risk matrix
  averageimpactscore = @impactarray.compact.inject(0) {|sum,x| sum += x.to_i } / @impactarray.compact.length
  averagelikelihoodscore = @likelihoodarray.compact.inject(0) {|sum,x| sum += x.to_i } / @likelihoodarray.compact.length
  overallscore = (averageimpactscore + averagelikelihoodscore) / 2
  @risk.update_column("average_impact", averageimpactscore)
  @risk.update_column("average_likelihood", averagelikelihoodscore)
  @risk.update_column("overall_score", overallscore)
  @risk.save!
  #N.B. remember we got simple form to recall the user's values so they 
  #do not get put back to 0 when other fields are edited (see the risk form view)
  flash[:success] = "Risk #{@risk.id} has been updated."
  redirect_to root_url
else
    render 'new'
end
end

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM