Two of the models I have in the rails 4 app are the following:
class Council < ActiveRecord::Base
has_many :alternatives
...
end
class Alternative < ActiveRecord::Base
belongs_to :council
...
end
I am rendering an Alternative form that allows me to create a new Alternative object from a Council's show view:
<%= 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 %>
At that point, I want to associate the Alternative object with the specific Council object from the show view, like the code below, but the variable @council is not defined:
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
That will allow me to show all the alternatives associated with a certain Council object:
...
<% @council.alternatives.each do |alternative| %>
<%= alternative.title %>
<%= alternative.more_info %>
<% end %>
...
I've carefully reviewed the Ruby on Rails Guides (http://guides.rubyonrails.org/association_basics.html#belongs-to-association-reference) but clearly I am missing something. Any ideas? Thank you.
Several options for you:
Nested
I've not tested this, but you could use multiple objects in your form_for
helper:
#app/views/councils/show.html.erb
<%= form_for [@council, @alternative] do |f| %>
...
<% end %>
This will send your request through to the council_alternatives_path
(you can change it), and provide you with params[:council_id]
and params[:id]
You could set your routes like this to get it to work:
#config/routes.rb
resources :councils do
resources :alternatives, only: [:create]
end
This will be a little hacky I think (as it's meant for forms with nested
attributes), but it's still a viable way to achieve what you want
Nested Attributes
The other option is to use the accepts_nested_attributes_for
directive in your model. This will be overkill for what you need I think, but could help:
#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
This will allow you to use the @council
object to save any new Alternative
objects you need:
#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
This will allow you to use the following form code:
#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 %>