Associate Pre-existing Record with Pre-Existing Parent (2 parent objects)
-
19-06-2021 - |
Question
I have several models in nested attributes that I'm working with.
I have "teams" (has many constests), and "contests" (belongs to Team). But I also want contests to reference "categories" as a child object (a contest can only have one category, and a category can have may contests).
The way the logic works is that a team is created first, then a contest, and after that I want to be able to select from a list of categories (in a partial) and establish the association (set the category_id in contest to the id value in a category). It makes sense to me how this is done when creating a new contest as a child of team, but I am hitting my head agains the wall when it comes to creating the second relationship (existing contest to an existing parent category).
The controller that gives me the show view for a contest is:
def show
@team = Team.find(params[:team_id])
@contest = Contest.find(params[:id])
@categories = Category.all
respond_to do |format|
format.html # show.html.erb
format.json { render json: [@contest] }
end
end
In the show view I have this code:
<p><b>Name:</b><%= @contest.name %></p>
<%= link_to 'Edit', edit_team_contest_path(@team, @contest) %> |
<%= link_to 'Back', team_contests_path %>
<br />
<%= render 'categories/index'%>
And my partial _index for categories contains this code:
<table>
<% @categories.each do |category| %>
<tr>
<td><%= category.level1 %></td>
<td><%= category.level2 %></td>
<td><%= category.level3 %></td>
<td><%= category.level4 %></td>
<td><%= link_to 'Show', category %></td>
<td><%= link_to 'Edit', edit_category_path(category) %></td>
<td><%= link_to 'Destroy', category, confirm: 'Are you sure?', method: :delete %></td>
<%end%>
</table>
Where I am so flummoxed is where to place the code (in the Contest or Category controller?) for setting the category-contest parent-child relationship, as well as which view (the Contest show view, or the Category _index partial?). I am pretty certain that I am not understanding something fundamental about Rails here, so if anyone could point me to the docs that might clear up my befuddlement I'd very much appreciate it.
La solution
Okay, here's how I ended up solving my problem (in case anyone finds it later and uses the same search terms I tried):
Models:
team.rb
has_many :contests, :dependent => :destroy
category.rb
has_many :contests
contest.rb
belongs_to :team, :foreign_key => "team_id"
belongs_to :category, :class_name => 'Category', :foreign_key =>"category_id"
accepts_nested_attributes_for :category
Controller:
contests_controller
def update
@contest = Contest.find(params[:id])
@team = @contest.team
if !params[:category_id].nil?
@category = Category.find(params[:category_id])
@contest.update_attributes(:category_id => @category.id)
end
respond_to do |format|
if @contest.update_attributes(params[:contest])
blah
else
blah
end
end
end
Categories View (_index), a partial in the contests/show view, includes these three bits of code:
<table>
<% @categories.each do |category| %>
<tr>
<td><%= form_for [category, @contest] do |f| %>
<% f.submit "Select" %>
<% end %></td>
</tr>
<%end%>
</table>
And that is what it takes to associate a record that belong to another parent with another parent in a different model (after the first relationship has been created).