我试图理解如何做一件简单的事情 - 保存一个id和来自collection_select的文本。 我刚刚开始使用RoR,所以我还没有很好地掌握一切。 我的经验主要是Java加上一些Perl,所以也许我没有选择正确的方法。
我有一个带有DefectRootCause的缺陷。 还有另一个实体DefaultRootCauses,我可以从中选择DefectRootCause.root_cause来关联缺陷。 我试图用它的DefectRootCause保存缺陷。 DefectRootCause应该将root_cause字段作为文本,从DefaultRootCause中选择值。 问题是我只是为DefectRootCause保存了一个root_cause或default_root_cause_id。 更多,DefectRootCause.root_cause获取DefaultRootCause而不是文本的id。
请让我知道我是否正确地试图让一切都发生并且#34;神奇地"或者我是否应该对控制器中的数据进行一些处理。 请参阅下面的代码。
我有模特:
class Defect < ActiveRecord::Base
has_one :defect_root_cause, :dependent => :destroy
has_many :default_root_cause, :through => :defect_root_cause
end
class DefectRootCause < ActiveRecord::Base
belongs_to :defect
belongs_to :default_root_cause
end
class DefaultRootCause < ActiveRecord::Base
has_many :defect_root_causes
has_many :defects, :through => :defect_root_causes
end
控制器(我认为我只需更改其中一个):
# POST /defects
# POST /defects.json
def create
#I am doing this because the attributes are not named :defect_root_cause_attribues, I don't know yet why
@defect = Defect.new(defect_params.except(:defect_root_cause))
@defect.defect_root_cause = DefectRootCause.new(defect_params[:defect_root_cause])
respond_to do |format|
if @defect.save
format.html { redirect_to @defect, notice: 'Defect was successfully created.' }
format.json { render :show, status: :created, location: @defect }
else
format.html { render :new }
format.json { render json: @defect.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /defects/1
# PATCH/PUT /defects/1.json
def update
respond_to do |format|
#I am doing this because the attributes are not named :defect_root_cause_attribues, I don't know yet why
if @defect.update(defect_params.except(:defect_root_cause)) && @defect.defect_root_cause.update(defect_params[:defect_root_cause])
format.html { redirect_to @defect, notice: 'Defect was successfully updated.' }
format.json { render :show, status: :ok, location: @defect }
else
format.html { render :edit }
format.json { render json: @defect.errors, status: :unprocessable_entity }
end
end
end
# Never trust parameters from the scary internet, only allow the white list through.
def defect_params
#I am doing this because the attributes are not named :defect_root_cause_attribues, I don't know yet why
params.require(:defect).permit(:details, defect_root_cause: [:id, :details, :root_cause, :default_root_cause_id])
end
现在视图:
<%= form_for @defect do |f| %>
<% if @defect.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@defect.errors.count, "error") %> prohibited this defect from being saved:</h2>
<ul>
<% @defect.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :details %><br>
<%= f.text_field :details %>
<%= f.fields_for @defect.defect_root_cause do |drc| %>
<%= drc.label :root_cause%>
<%= drc.collection_select(:default_root_cause_id, DefaultRootCause.all, :id, :root_cause, :prompt => true) %>
<%= drc.label :details%>
<%= drc.text_field :details %>
<% end %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
在routes.rb中我只有以下内容:
resources :default_root_causes
resources :defects
resources :defect_root_causes
# You can have the root of your site routed with "root"
root 'defects#index'
最后,我的问题(root_cause是nil):
irb(main):006:0> DefectRootCause.find(10)
DefectRootCause Load (0.3ms) SELECT `defect_root_causes`.* FROM `defect_root_causes` WHERE `defect_root_causes`.`id` = 10 LIMIT 1
=> #<DefectRootCause id: 10, details: "sadsad", defect_id: 9, default_root_cause_id: 2, created_at: "2016-02-19 05:52:06", updated_at: "2016-02-19 05:52:06", root_cause: nil>
如果我将选择更改为:
<%= drc.collection_select(:root_cause, DefaultRootCause.all, :id, :root_cause, :prompt => true) %>
我得到以下内容(root_cause被保存,但它是一个数字而不是文本 - 在这种情况下我想要以下文本:&#34;第二个根本原因&#34;,加上default_root_cause_id是nil):
irb(main):005:0> DefectRootCause.find(9)
DefectRootCause Load (0.3ms) SELECT `defect_root_causes`.* FROM `defect_root_causes` WHERE `defect_root_causes`.`id` = 9 LIMIT 1
=> #<DefectRootCause id: 9, details: "das", defect_id: 8, default_root_cause_id: nil, created_at: "2016-02-19 05:42:36", updated_at: "2016-02-19 05:42:36", root_cause: "2">
编辑:
现在我发布了我所做的工作,以便将所有信息保存到我需要的地方。 我现在发帖作为答案,因为我仍然不知道这是否是正确的做法。 所以,如果你知道它应该以不同的方式完成,请告诉我。我特别关注如何从视图中发送所有信息。我看到了这个观点&#34;知道&#34;所选DefaultRootCause的id和文本,但我不能同时在发送的params中获取。
所以,现在是代码。
查看:
<%= drc.select :default_root_cause_id, DefaultRootCause.all.collect{|r| [r.root_cause, r.id]}, :prompt => true %>
defects_controller.rb
def create
@defect = Defect.new(defect_params.except(:defect_root_cause))
@defect.defect_root_cause = DefectRootCause.create(defect_params[:defect_root_cause].merge(:root_cause => DefaultRootCause.find(defect_params[:defect_root_cause][:default_root_cause_id]).root_cause))
respond_to do |format|........
def update
respond_to do |format|
if @defect.update(defect_params.except(:defect_root_cause)) && @defect.defect_root_cause.update(defect_params[:defect_root_cause].merge(:root_cause => DefaultRootCause.find(defect_params[:defect_root_cause][:default_root_cause_id])))
通过这些我得到以下参数以及以下插入:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"jGUQIxeXWZwg5lqsPFrE4vO9z4ioRnAN/Z1/K9scQiIeQ0MTHBTvZoDcwHKtGvrgrG53y4yr7tX4wnCShoZ/oA==", "defect"=>{"details"=>"a", "defect_root_cause"=>{"default_root_cause_id"=>"2", "details"=>"a"}}, "commit"=>"Create Defect"}
DefaultRootCause Load (0.1ms) SELECT `default_root_causes`.* FROM `default_root_causes` WHERE `default_root_causes`.`id` = 2 LIMIT 1
CACHE (0.0ms) SELECT `default_root_causes`.* FROM `default_root_causes` WHERE `default_root_causes`.`id` = 2 LIMIT 1 [["id", "2"]]
CACHE (0.0ms) SELECT `default_root_causes`.* FROM `default_root_causes` WHERE `default_root_causes`.`id` = 2 LIMIT 1 [["id", "2"]]
(0.1ms) BEGIN
SQL (0.2ms) INSERT INTO `defect_root_causes` (`details`, `default_root_cause_id`, **`root_cause`**, `created_at`, `updated_at`) VALUES ('a', 2, **'second root cause'**, '2016-02-23 07:10:59', '2016-02-23 07:10:59')
现在,请告诉我这是否是&#34;正确的&#34;这样做的方法。
谢谢你, 维克多
答案 0 :(得分:0)
您正尝试通过父级更新关联的属性,这意味着您需要使用accepts_nested_attributes_for
。将此方法添加到Defect
模型中,如下所示:
类缺陷&lt;的ActiveRecord ::基
has_one:defect_root_cause,:dependent =&gt; :破坏 has_many:default_root_cause,:through =&gt; :defect_root_cause
accepts_nested_attributes_for:defect_root_cause 端
完成此操作后,转到defects_controller.rb
并将#defect_params
方法更新为:
params.require(:defect).permit(:details, defect_root_cause_attributes: [:id, :details, :root_cause, :default_root_cause_id])
答案 1 :(得分:0)
您可以使用以下代码:
<%=f.select :default_root_cause_id, DefaultRootCause.all.collect{|r| [r.route_cause,"#{r.route_cause} - #{r.id}"]} %>