我在rails 4应用程序中拥有的两个模型如下:
class Council < ActiveRecord::Base
has_many :alternatives
...
end
class Alternative < ActiveRecord::Base
belongs_to :council
...
end
我正在渲染一个Alternative表单,允许我从Council的节目视图中创建一个新的Alternative对象:
<%= render 'alternatives/form' %>
<%= form_for(@alternative) do |f| %>
<div class="form-group">
<div>
<%= f.text_field :title, :placeholder => 'Provide your alternative', autofocus: true, class:"form-control" %>
</div>
<div>
<%= f.text_area :more_info, :placeholder => 'Describe your alternative', autofocus: true, class:"form-control", rows: '4' %>
</div>
</div>
<div>
<%= f.submit 'Submit the alternative!', class:"btn btn-success" %>
</div>
<% end %>
此时,我希望将Alternative对象与show视图中的特定Council对象相关联,如下面的代码,但未定义变量@council:
class AlternativesController < ApplicationController
before_action :set_alternative, only: [:show, :edit, :update, :destroy]
def create
@alternative = Alternative.new(alternative_params)
@alternative.council = @council
end
private
def set_alternative
@alternative = Alternative.find(params[:id])
end
def alternative_params
params.require(:alternative).permit(:title, :more_info)
end
end
这将使我能够显示与某个理事会对象相关的所有替代方案:
...
<% @council.alternatives.each do |alternative| %>
<%= alternative.title %>
<%= alternative.more_info %>
<% end %>
...
我仔细阅读了Ruby on Rails指南(http://guides.rubyonrails.org/association_basics.html#belongs-to-association-reference),但显然我遗漏了一些东西。有任何想法吗?谢谢。
答案 0 :(得分:0)
routes.rb
看起来像什么?在这种情况下,最简单的方法是将alternative
嵌套在council
路线下,如下所示:
在这种情况下,在创建操作的alternatives_controller.rb
中,您只需从参数中设置@council
对象。
即
def create
@council = Council.find(params[:council_id])
@alternative = Alternative.new(alternative_params)
@alternative.council = @council
@alternative.save
end
答案 1 :(得分:0)
就我个人而言,我会将它嵌入路线中的derekyau(https://stackoverflow.com/a/25109545/3105349)
但你也可以使用表格中的隐藏字段来传递议会身份,即
<%= hidden_field :council_id, @council.id %>
然后在控制器中,您可以通过参数
访问它@council = Council.find(params[:alternative][:council_id])
或将其添加到您的备用参数中以自动分配
def alternative_params
params.require(:alternative).permit(:title, :more_info, :council_id)
end
但同样,使其成为嵌套路线是更清洁和首选的解决方案。
答案 2 :(得分:0)
有几种选择:
<强>嵌套强>
我没有对此进行测试,但您可以在form_for
帮助器中使用多个对象:
#app/views/councils/show.html.erb
<%= form_for [@council, @alternative] do |f| %>
...
<% end %>
这会将您的请求发送到council_alternatives_path
(您可以更改),并为您提供params[:council_id]
和params[:id]
您可以像这样设置路线以使其发挥作用:
#config/routes.rb
resources :councils do
resources :alternatives, only: [:create]
end
我认为这有点像hacky(因为它适用于具有nested
属性的表单),但它仍然是实现你想要的可行方式
嵌套属性
另一种选择是在模型中使用accepts_nested_attributes_for
指令。这对于我认为你需要的东西来说太过分了,但可以提供帮助:
#app/models/council.rb
Class Council < ActiveRecord::Base
has_many :alternatives
accepts_nested_attributes_for :alternatives
end
#app/models/alternative.rb
Class Alternative < ActiveRecord::Base
belongs_to :council
end
这将允许您使用@council
对象保存所需的任何新Alternative
对象:
#app/controllers/councils_controller.rb
Class CouncilsController < ApplicationController
def show
@council = Council.find params[:id]
@council.alternatives.build
end
def update
@council = Council.find params[:id]
@council.update(council_params)
end
private
def council_params
params.require(:council).permit(alterantives_attributes: [:alternatives, :attributes])
end
end
这将允许您使用以下表单代码:
#app/views/councils/show.html.erb
<%= form_for @council do |f| %>
<%= f.fields_for :alternatives do |a| %>
<%= a.text_field :your_info %>
<% end %>
<% f.submit %>
<% end %>