I am sitting here since the Dawn of Times trying to toggle a boolean in Rails for an admin to validate submissions.
I have a standard "Article" model, which has_many "Prosols" (which in turn belongs_to "Article"). A Prosol has a boolean "profeat1". I am trying to toggle it thanks to a set of button_to (as follows). I am looping through the articles prosols, showing them in a bootstrap template, and showing for each a button to validate or not. The issue is that all buttons point to the first prosol. It seems that the prosol ID is not accurately passed to the controller.
No route matches {:action=>"unpro1", :article_id=>5, :controller=>"prosols", :id=>nil} missing required keys: [:id]
Here is the code.
article#show.html.erb - Adding lines from original Code
<% if admin_signed_in? %>
<% @article.prosols.in_groups_of(2) do |group| %>
<div class="container-fluid">
<% group.compact.each do |prosol| %>
<div class="col-md-6">
<div class="box3">
<h4><%= prosol.title %></h4> <br>
<%= prosol.body %> <br>
<% if prosol.profeat1 == false %>
<%= button_to "Do it", pro1_article_prosol_path(:article_id => @article.id, :id => @prosol.id), :class => 'btn btn-info'%>
<% else %>
<%= button_to "Undo it", unpro1_article_prosol_path(:article_id => @article.id, :id => @prosol.id), :class => 'btn btn-info'%>
<% end %>
</div>
</div>
<% end %>
</div>
<% end %>
<% end %>
prosols_controller.rb
def pro1
@article = Article.find(params[:article_id])
@prosol = @article.prosols.find(params[:id])
@prosol.update(profeat1: true)
redirect_to article_path(@article)
end
def unpro1
@article = Article.find(params[:article_id])
@prosol = @article.prosols.find(params[:id])
@prosol.update(profeat1: false)
redirect_to article_path(@article)
end
routes.rb
resources :articles do
resources :prosols do
post 'pro1', on: :member
post 'unpro1', on: :member
end
end
Right now I think the issue is with passing the nested resource (prosol) ID to controller. If you see a better/different way of achieving the end result, I will warmly welcome your advice. Again, my goal is to display all prosols for an article, with an admin button to validate or not. I have thoroughly tried everything else on StackO so far but to no avail.
Awaiting the Savior... Thanks in advance.
EDIT : THIS IS THE SOLUTION - article#show.html.erb
<% if prosol.profeat1 == false %>
<%= button_to "Do it", pro1_article_prosol_path(:article_id => @article.id, :id => prosol.id), :class => 'btn btn-info'%>
<% else %>
<%= button_to "Undo it", unpro1_article_prosol_path(:article_id => @article.id, :id => prosol.id), :class => 'btn btn-info'%>
<% end %>
My initial error had 2 sources: - pointing to the nested prosol with an @ instead of no pointer, as it was already pointed to in the loop - and bad leftovers in the Articles controller, as follows:
def show
@article = Article.find(params[:id])
@prosols = @article.prosols.all <--- wrong
@prosol = @article.prosols.build <--- wrong
end
Great. Now it's beer o'clock.
The issue appears to be that you are using @prosol in your button, which has not been assigned and is therefore returning nil.
Your loop defined in your comment, sets prosol, which is not @prosol. Drop the '@' symbol and you should be fine.
-- edit--
As in id => prosol.id
...
<% if prosol.profeat1 == false %>
<%= button_to "Do it", ..., :id => prosol.id), :class => 'btn btn-info'%>
<% else %>
<%= button_to "Undo it", ..., :id => prosol.id), :class => 'btn btn-info'%>
<% end %>
Your error is showing id => nil
because @prosil is a nil object.