如何将表单中的值插入数据库中的数组?我使用简单的形式,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
我想象代码看起来像这样,但唉,我的第一个rails项目,我需要一些指导。在risk_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插入值。因此,如果用户标识为3,则他们提交的表单中的值应该进入数组中的第3个插槽。
答案 0 :(得分:0)
你必须在强参数中定义post值是数组。
def risk_params
params.require(:risk).permit(:description, :title, :area, :owner, :action, :date_of_action, :action_completed, {:impact => []}, {:likelihood=>[]})
end
答案 1 :(得分:0)
对于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