Ruby on Rails, controller doesn't seem to be linking to view - ruby-on-rails

In my index.html.erb file, this lot of code works:
<% if Restaurant.all.any? %>
<% Restaurant.all.each do |restaurant| %>
<h2><%= restaurant.name %></h2>
<% end %>
<% else %>
<h1>No restaurants yet!</h1>
<% end %>
<a href='#'>Add a restaurant</a>
However, when I change the controller to this:
class RestaurantsController < ApplicationController
def index
#restaurants = Restaurant.all
end
end
and the index.html.erb file to this:
<% if #restaurants.any? %>
<% #restaurants.each do |restaurant| %>
<h2><%= restaurant.name %></h2>
<% end %>
<% else %>
<h1>No restaurants yet!</h1>
<% end %>
<a href='#'>Add a restaurant</a>
all of the tests which passed, now fail because of that change, and I can't for the life of me work out why they are not working. The error message when running the tests is:
Failure/Error: visit '/restaurants'
ActionView::Template::Error:
undefined method `any?' for nil:NilClass
My routes.rb file is as follows:
Rails.application.routes.draw do
resources :restaurants
end

Actually the problem is that your index is called directly without going to controller. So earlier your "Restaurant.all" works correctly but now atfer new changes #restuanants is null and you applied null.any?. It gives error.
try
<% if #restaurants && #restaurants.any? %>
or
<% unless #restaurants.blank? %>

Try this I hope this will help
In index.html.erb
<% unless #restaurants.blank? %>
<% #restaurants.each do |restaurant| %>
<h2><%= restaurant.name %></h2>
<% end %>
<% else %>
<h1>No restaurants yet!</h1>
<% end %>
<a href='#'>Add a restaurant</a>

Related

Rails 4 params not being sent to the controller

I have been battling with what is going to turn out to be a quick answer for someone...
I have view with nested partials. The index has a partial to the categories which has a partial to the subcategories.
The categories are looping as expected but for some reason the locals don't seem to be reaching the controller.
My code is as follows:
index.html.erb
<%= render partial: "categories/categories", object: #categories %>
_categories.html.erb
<% #categories.each do |category| %>
<% if category.category_parent == 0 %>
<li><%= category.category_name %> <i class="icons icon-right-dir"></i>
<%= render partial: "categories/subcategories", object: #subcategories, locals: {parent_id: category.category_id} %>
</li>
<% end %>
<% end %>
_subcategories.html.erb
<% if #parent != nil %>
<ul class="sidebar-dropdown">
<li>
<ul>
<% #subcategories.each do |subcategory| %>
<li><%= subcategory.category_name %> <i class="icons icon-right-dir"></i></li>
<% end %>
</ul>
</li>
</ul>
<% end %>
categories_controller.rb
class CategoriesController < ApplicationController
before_action :categories, :subcategories
def categories
#categories = Category.all
end
def subcategories
#parent = params[:parent_id]
#subcategories = Category.where(:category_parent => params[:parent_id])
end
end
#categories is an instance variables, and you shouldn't need to pass it from view to view. So the first render statment becomes:
<%= render "categories/categories" %>
(I'm more familiar leaving off partial:)
_categories.html.erb becomes this:
<% #categories.each do |category| %>
<% if category.category_parent == 0 %>
<li><%= category.category_name %> <i class="icons icon-right-dir"></i>
<%= render "categories/subcategories", category: category %>
<%# Note passing in category to have access to it as a local %>
</li>
<% end %>
<% end %>
_subcategories.html.erb
<% if category != nil %>
<ul class="sidebar-dropdown">
<li>
<ul>
<% category.subcategories.each do |subcategory| %>
<li><%= subcategory.category_name %> <i class="icons icon-right-dir"></i></li>
<% end %>
</ul>
</li>
</ul>
<% end %>
I don't think you should be looking up #subcategories in your controller. It looks like in def categories you're just getting all the categories and then looping through them in the view. As it is, this will be n+1, as every time it loops over a new category, it will have to do a db query to find its subcategories. You can avoid this with includes.
categories_contorller.rb
def categories
#categories = Category.all.includes(:subcategories)
end
This is what I think is simplest and clearest. But I also haven't played with object: too much. This post might help you if you want to stick to that pattern:

How do I check CanCan abilities on an object in a `shared/partial`?

Per the CanCan documentation, to check if a user has the ability to do something to any element in the view, you do something like this:
<% if can? :create, #project %>
<%= link_to "New Project", new_project_path %>
<% end %>
Or you can check with the class like:
<% if can? :create, Project %>
<%= link_to "New Project", new_project_path %>
<% end %>
In my case, I have a DashboardController#Index, that has this:
#nodes = current_user.nodes.where(:is_comment => nil)
In my views/dashboard/index.html.erb, I have this:
<% #nodes.each do |node| %>
<!-- Upload Video Comment Popup -->
<div class="box">
<%= render partial: "shared/comments", locals: {node: node} %>
</div>
<% end %> <!-- node -->
Then in my shared/_comments.html.erb, I have this:
<% if node.comments.present? %>
<% node.comments.each do |comment| %>
<% if can? :manage, Comment %>
Show Something Interesting Here
<% else %>
Show something boring here
<% end %>
<% end %>
<% end %>
That doesn't work.
I also tried this:
<% if node.comments.present? %>
<% node.comments.each do |comment| %>
<% if can? :manage, comment %>
Show Something Interesting Here
<% else %>
Show something boring here
<% end %>
<% end %>
<% end %>
And that doesn't work either.
This is my ability.rb
can :manage, Comment, user_id: user.id
I thought about creating a #comments instance variable in the controller, but the issue with that is that the comments are on a collection of nodes (i.e. I need to show multiple nodes, and each node has multiple comments).
How do I approach this?
Your last code should work after updating to CanCanCommunity version of cancan
<% if node.comments.present? %>
<% node.comments.each do |comment| %>
<% if can? :manage, comment %>
Show Something Interesting Here
<% else %>
Show something boring here
<% end %>
<% end %>
<% end %>
related to How do I show an error for unauthorized can can access

Undefined method each with nested resources

I'm trying to follow Ryan Bates Polymorphic association tutorial in order to put some comments to my site.
The thing is I have nested resources:
#Nesting Resources
resources :users do
resources :photos do
resources :comments
resources :tags
end
end
So I'm getting an error in my view (photos/show)
undefined method `each' for nil:NilClass
I suppose the problem is in my controller, with comments, that is not defined correctly, but since I have nested resources, I don't know how to do it.
Photos Controller
def show
#photo = Photo.friendly.find(params[:id])
#user = #photo.user
#commentable = #photo
#comments = #commentable.comments
#comment = Comment.new
end
New Comment Partial
<h2>Comments</h2>
<% if #comments.any? %>
<%= render "comments/comments" %>
<% else %>
TodavĂ­a no hay comentarios
<% if user_signed_in? %>
<%= render "comments/form" %>
<% end %>
<% end %>
Form partial (comments/form)
<%= form_for [#commentable, #comment] do |f| %>
<% if #comment.errors.any? %>
<div class="error_messages">
<h2>Please correct the following errors.</h2>
<ul>
<% #comment.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.text_area :content, rows: 8 %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Comments partial (comments/comments)
<div id="comments">
<% #comments.each do |comment| %>
<div class="comment">
<%= simple_format comment.content %>
</div>
<% end %>
</div>
Your error says undefined method each for nil:NilClass. As you can guess you are calling each on a nil object. Here your #comments is nil and hence giving your trouble.
In your view try something like this:
<div id="comments">
<% if #comments %>
<% #comments.each do |comment| %>
<div class="comment">
<%= simple_format comment.content %>
</div>
<% end %>
<% end %>
</div>
Edit:
So if you look at your code you have #comments till here:
<% if #comments.any? %>
<%= render "comments/comments" %>
<% else %>
#do stuff
<% end %>
it's after you call your partial that your #comment is lost so try this:
<% if #comments.any? %>
<%= render "comments/comments", comments: #comment %>
<% else %>
#do stuff
<% end %>
and then in your view use
<div id="comments">
<% comments.each do |comment| %>
<div class="comment">
<%= simple_format comment.content %>
</div>
<% end %>
</div>

Trying to output the columns for a collection of Models

My controller:
def testing
#models = [User, Products]
end
testing.html.erb:
<% #models.each do |m| %>
<%= render partial: "details", model: m %>
<% end %>
_details.html.erb:
<% #m.columns.each do |c| %>
<li><%= c.name %></li>
<% end %>
I am getting the error:
undefined method `columns' for nil:NilClass
I'm not sure why this doesn't works.
My code worked fine when I was using a single Active Record Model, now I want to be able to do the same thing with an Array of Models, so I broke my template out into a partial so I can loop through my models and output this information.
What seems to be the problem?
Update
Strange because this works fine:
<% #models.each do |m| %>
<%= m.columns %>
<% end %>
You are passing local variable model to your _detail view partial and calling instance variable #m. Change your code in the testing.html.erb to
<% #models.each do |m| %>
<%= render partial: "details", locals: { model: m } %>
<% end %>
and _details.html.erb to
<% model.columns.each do |c| %>
...
Try this:
<% #models.each do |m| %>
<%= render partial: "details", locals: {model: m} %>
<% end %>
And in the _details.html.erb:
<% model.columns.each do |c| %>
<li><%= c.name %></li>
<% end %>

RAILS HABTM checkboxes don't update

I am trying to realize HABTM checkboxes following this tutorial:
http://www.justinball.com/2008/07/03/checkbox-list-in-ruby-on-rails-using-habtm/
While everything seems to work nicely the updates are not saved to my database.
My controller looks like the following:
class UserrolesController < ApplicationController
before_action :set_userrole
def edit
#projects=Project.all
end
def update
params[:userrole][:project_ids] ||= []
#userrole = Userrole.find(params[:id])
if #userrole.update_attributes(userrole_params)
flash[:notice] = "Settings have been saved."
redirect_to edit_userrole_url(#userrole)
else
flash.now[:error] = #userrole.errors
setup_form_values
respond_to do |format|
format.html { render :action => :edit}
end
end
end
private
def set_userrole
#userrole = Userrole.find(params[:id])
end
def userrole_params
params.require(:userrole).permit(:name, :project_ids)
end
end
My _form.html.erb like this:
<%= form_for(#userrole) do |f| %>
<% if #userrole.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#userrole.errors.count, "error") %> prohibited this person from being saved:</h2>
<ul>
<% #userrole.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="center">
<div class="field">
<%= f.label :Name %>
<%= f.text_field :name %>
</div>
<ul class="checkbox-list">
<% #projects.each do |project| -%>
<li><%= check_box_tag "userrole[project_ids][]", project.id, userrole_edits_project?(project) -%> <%= project.name -%></li>
<% end -%>
</ul>
<div class="actions">
<%= f.submit "Speichern", class: "btn btn-primary" %>
</div>
</div>
<% end %>
So I did everything like in the tutorial, the :name is saved without any problems, but the ids are not saved to the database. There is no error message. Does anybody has an idea what might go wrong? Maybe some missing permission somewhere?
So finally I found a work around for this problem.
I forced the update of project_ids by adding the following line in def update:
#userrole.project_ids=params[:userrole][:project_ids]

Resources