Link to image of what I'm talking about
My problem is that there is an extra template being rendered at the bottom of my list without an item id. The icons delete the item they are next to when clicked. The bottom icon is showing up even though it has no item related to it.
Here is my the show html.erb
<div class="row">
<div class="col-md-8">
<div class="media">
<br />
<div class="media-body">
<h3><%= #user.email %></h3>
<br />
<%= render partial: 'items/form', locals: {user: #user} %>
<div class="media">
<div class="media-body">
<h4 class="media-heading">
<ul>
<%= render #items %>
</ul>
</h4>
</div>
</div>
</div>
</div>
</div>
Here is my _item template
<li><%= item.name %><%= link_to "", [current_user, item], remote: true, method: :delete, class: 'glyphicon glyphicon-ok' %></li>
Here is my items controller
class ItemsController < ApplicationController
def create
#item = Item.new(item_params)
#item.user = current_user
if #item.save
flash[:notice] = "Item was saved."
redirect_to user_path(current_user.id)
else
flash.now[:alert] = "There was an error saving the item. Try again."
redirect_to user_path(current_user.id)
end
end
def destroy
#item = Item.find(params[:id])
if #item.destroy
flash[:notice] = "Item deleted"
redirect_to user_path(current_user.id)
else
flash.now[:alert] = "Error deleting the item."
redirect_to user_path(current_user.id)
end
end
private
def item_params
params.require(:item).permit(:name)
end
end
Here is my users controller
class UsersController < ApplicationController
def show
#user = current_user
#item = Item.new
#items = #user.items
end
end
The items belong to the users and have nested routes under user. The last checkmark (the one I want to get rid of) when hovered over shows the link .../users/6/items, while the others that next to items show .../users/6/items/40
Here is my _form.html.erb for items:
<%= form_for [user, user.items.new] do |f| %>
<%= f.text_field :name, class: 'form-control', placeholder: "Enter your to-do item", value: nil, required: true %>
<div class="form-group">
<%= f.submit "Save", class: 'btn btn-success' %>
</div>
<% end %>
Remove
#item = Item.new
from show action in users controller.
class UsersController < ApplicationController
def show
#user = current_user
#items = #user.items
end
end
Related
Trying to make sub categories of categories in nested resources. The issue that I have is that it doesn't seem to work. All i get are undefined methodsub_category_path' for #<#:0x007f8fcde33550>
Did you mean? new_category_pathswell asfirst value of a form cannot be nil`.
My controller methods are as follows:
SubCategory Update:
#category = #subcategory.category.id
if #subcategory.update(subcategory_params)
flash[:success] = "Subcat name updated"
redirect_to category_sub_category_path(#subcategory)
else
render 'edit'
end
SubCategory new:
#category = Category.find(params[:category_id]) # TODO:subcategory.category.id?
#category_sub = #category.sub_categories.new
##subcategory = #category.sub_categories.new
SubCategory create:
#subcategory = SubCategory.new(subcategory_params)
if #subcategory.save
flash[:success] = "subcategory created"
redirect_to category_sub_category_path
else
flash[:error] = "subcategory failed"
render 'new'
end
And my private methods:
private
def set_sub_category
#subcategory = SubCategory.find(params[:id])
end
def subcategory_params
params.require(:sub_category).require(:name, :category_id)
end
end
I don't have a SubCategories index, the viewing of the SubCategory is based off clicking a link in Categories index.html.erb which can be seen here:
<%#categories.each do |c|%>
<ul class="listing">
<div class="row">
<div class="well col-md-4 col-md-offset-4">
<li class="article-title">
<strong><%= link_to "#{c.name}", category_path(c)%></strong>
<% c.sub_categories.each do |s|%>
<div>
<%=link_to s.name, category_sub_category_path(c,s)%>
</div>
<%end%>
</li>
<li><small>
<!--Pluralise here-->
</small></li>
</div>
</div>
</ul>
<%end%>
And then in my SubCategory show.html.erb:
<span class ="badge"><%= link_to "Edit sub category name",
edit_category_sub_category_path([#category, #subcategory])%></span>
And in my SubCategory edit.html.erb:
<%=form_for([#category, #subcategory], :html => {class: "form-horizontal", role: "form"})do |f|%>
<div class="form-group">
<div class="control-label col-sm-2">
<%= f.label :subcategory%>
</div>
<div class="col-sm-8">
<%= f.text_field :name, class: "form-control", placeholder: "Update Sub Category", autofocus: true%>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<%=f.submit class: "btn btn-primary btn-lg"%>
</div>
</div>
<%end%>
Any help would be appreciated
EDIT:
Errors
am now getting this error
{"utf8"=>"✓", "_method"=>"patch", "authenticity_token"=>"81lwz0NufTqdOni+4wPRO4Vnmeis9f32+sqSNsxTXZY7ufyR8hTvF86KQwdMjcOP2DQJibK66croW48Uhos9+A==", "sub_category"=>{"name"=>"Gold", "category_id"=>"1"}, "commit"=>"Update Sub category", "category_id"=>"1", "id"=>"1"}
because wrong number of arguments (given 2 expects 1)
def
subcategory_params params.require(:sub_category).require(:name, :category_id)
end
FIXED: Just took out the second .require, no idea why I put that there
As you have mentioned in the comments the edit action must be like
def edit
#subcategory = SubCategory.find(params[:id])
end
So the value #category is nil this has caused a error first value of a form cannot be nil.
Make the edit action as
def edit
#subcategory = SubCategory.find(params[:id])
#category = #subcategory.category
end
Assuming that you have relation between category and sub category.
Took me a while but finally was able to have a user_id and friend_id associate with each other through friendships model. The problem I'm having is:
When clicking "add friend"
<% #users.each do |user| %>
<% if user.user_name != current_user.user_name %>
<% if #friendshiplink.nil? %>
<%= user.user_name %>
<%= link_to "Add Friend", friendships_path(friend_id: user.id), method: :post %>
<% else %>
<%= link_to(
("Unfollow"),
"/friendships/#{ #friendship.id }",
method: :delete ) %>
<% end %>
<% end %>
<% end %>
I get in respond is:
undefined method `id' for nil:NilClass
Extracted source (around line #86):
<% else %>
<%= link_to(
("Unfollow"),
"/friendships/#{ #friendship.id }",
method: :delete ) %>
<% end %>
<% end %>
Please let me know if I'm missing any code in order to further understand what might be the issue
Rake Routes
friendships POST /friendships(.:format) friendships#create
friendship DELETE /friendships/:id(.:format) friendships#destroy
Friendship Controller
class FriendshipsController < ApplicationController
def create
# #friendship = current_user.friendships.build
# #friendship.friend_id = params[:friend_id]
# #friendship.user_id = current_user.id
#friendship = current_user.friendships.build(friend_id: params[:friend_id])
if #friendship.save
flash[:notice] = "Added friend."
redirect_to "/users/#{ params[:friend_id] }"
else
flash[:notice] = "Unable to add friend"
redirect_to root_url
end
end
def destroy
#friendship = current_user.friendships.find(params[:id])
#friendship.destroy
flash[:notice] = "Removed friendship."
redirect_to current_user
end
private
def friendship_params
params.require(:friendship).permit(:user_id, :friend_id)
end
end
User Controller
def index
#user = User.new
#users = User.all
if current_user
#leaders = #current_user.leaders
end
end
def create
#user = User.new(user_params)
if #user.save
session[:user_id] = #user.id
cookies[:user_id] = #user.id
flash[:notice] = "Successfully Registerd"
redirect_to "/"
else
flash[:alert] = #user.errors.full_messages
redirect_to "/"
end
end
def new
#user = User.new
end
def edit
#user = User.friendly.find(params[:id])
current_user
end
def show
#users = User.all
#user = User.friendly.find(params[:id])
current_user
if #current_user
#followerlink = Follower.where(leader_id: #user.id,
follower_id: #current_user.id).first
#friendshiplink = Friendship.where(friend_id: #user.id,
user_id: #current_user.id).first
end
end
def update
#user = User.friendly.find(params[:id])
if #user.update(user_params)
flash[:notice] = "You have successfully update your information"
redirect_to "/"
else
flash[:alert] = #user.errors.full_messages
redirect_to "/"
end
end
def destroy
#user = User.friendly.find(params[:id])
#user.destroy
end
private
def user_params
params.require(:user).permit(:background, :username_or_email, :first_name, :last_name, :email, :password, :user_name, :avatar, :gender, :zip_code, :birthdate)
end
Where code is in user/view
<div id="user_profile">
<div id="profile_top">
<p class="profile_logo"></p>
<nav>
<div class="profile_loginout">
<%= link_to ("LOGOUT"), "/sessions/new",method: :delete %>
</div>
<div class="profile_user-links">
<a href="/users/<%= current_user.id %>">
<% if current_user.user_name.present? %>
<%= link_to current_user.user_name, user_path(current_user) %>
<% else %>
<%= current_user.first_name %>
<% end %>
</a>
<b class="size">|</b>
Settings
<b class="size">|</b>
</div>
</nav>
</div>
<div id="profile_to">
<div class="profile_background_picture">
<%= image_tag #user.background.url(:medium) %>
</div>
<div class="profile_picture">
<%= image_tag #user.avatar.url(:medium) %>
</div>
</div>
</div>
<% if #current_user && #user.id != #current_user.id %>
<% if !#followerlink %>
<form action="/followers" method="POST">
<input type="hidden"
name="authenticity_token"
value="<%= form_authenticity_token %>">
<input type="hidden"
name="leader_id"
value=<%= #user.id %>>
<input type="submit" value="Follow" class="followlink">
</form>
<% else %>
<div class="followlink">
<%= link_to(
("Unfollow"),
"/followers/#{ #followerlink.id }",
method: :delete ) %>
</div>
<% end %>
<% end %>
<p>Username: <%= #user.user_name %></p>
<h2>Friends</h2>
<ul>
<% for friendship in #user.friendships %>
<li>
(<%= link_to "remove", friendship, method: :delete %>)
</li>
<% end %>
</ul>
<p><%= link_to "Find Friends", users_path %></p>
<h2> Users who Have Befriended you </h2>
<ul>
<% for user in #user.inverse_friends %>
<li> <%= h user.user_name %></li>
<% end %>
</ul>
<% #users.each do |user| %>
<% if user.user_name != current_user.user_name %>
<% if #friendshiplink.nil? %>
<%= user.user_name %>
<%= link_to "Add Friend", friendships_path(friend_id: user.id), method: :post %>
<% else %>
<%= link_to "Unfollow", friendships_unfollow_path(#friendship), method: :delete %>
<% end %>
<% end %>
<% end %>
Thank you for all the help or hints in solving the issue. Greatly appreciate it.
On top of my head, not sure it's working but try it...
In routes:
delete '/friendships/:id', to: 'friendships_controller#destroy', as: 'friendships_unfollow'
In view:
<%= link_to "Unfollow", friendships_unfollow_path(#friendship), method: :delete %>
It is unclear where do you get your #friendship variable.
I am working on a rails assignment that needs me to create a checkbox that destroys items on a to-do list. I am currently getting a undefined local variable or method `item,' but I don't think thats the overall problem with my items#destroy action. Should I be making item to be #item instead?
Items Controller:
class ItemsController < ApplicationController
def new
#user = User.find(params[:user_id])
#item = Item.new
end
def create
#user = User.find(params[:user_id])
#item = Item.new(params.require(:item).permit(:name))
#item.user_id = #user.id
if #item.save
flash[:notice] = "Item was saved."
redirect_to [#user, #item]
else
flash[:error] = "There was an error saving the item. Please try again."
render :new
end
end
def show
#user = User.find(params[:user_id])
#item = Item.find(params[:id])
end
def destroy
#user = User.find(params[:user_id])
#item = Item.find(params[:id])
if #item.destroy
flash[:notice] = "Item was removed."
else
flash[:error] = "Item couldn't be deleted. Try again."
end
respond_to do |format|
format.html
format.js
end
end
Destroy.js.erb
$('#item-' +<%= #item.id %>).hide();
Users Show:
<br>
<div class="container">
<div class="row">
<div class="col-md-11">
<div class="panel panel-default">
<div class="panel-body">
<div class="row">
<div class="col-md-12 lead">User profile<hr></div>
</div>
<div class="row">
<div class="col-md-4 text-center">
<img class="img-circle avatar avatar-original" style="-webkit-user-select:none;
display:block; margin:auto;" src="http://robohash.org/sitsequiquia.png?size=120x120">
</div>
<div class="col-md-8">
<div class="row">
<div class="col-md-12">
<h1 class="only-bottom-margin"><%= #user.email%></h1>
</div>
</div>
<div class="row">
<div class="col-md-6">
<span class="text-muted">Name:</span> <%= #user.name%><br>
<span class="text-muted">Id:</span> <%= #user.id %><br>
</div>
<div class="col-md-10">
<h3>User's To-Do List</h3>
<%= link_to "", item, method: :delete, class: 'glyphicon glyphicon-ok', remote: true %>
<%= render partial: 'items/item'%>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
By the time your view is called (i.e. destroy.js.erb), #item will be destroyed. Just add a variable that caches the item id:
def destroy
#user = User.find(params[:user_id])
#item = Item.find(params[:id])
#item_id = #item.id
if #item.destroy
flash[:notice] = "Item was removed."
else
flash[:error] = "Item couldn't be deleted. Try again."
end
respond_to do |format|
format.html
format.js
end
and then in your destroy.js.erb:
$('#item-' +<%= #item_id %>).hide();
I believe the error is being introduced in your view with the line:
<%= link_to "", item, method: :delete, class: 'glyphicon glyphicon-ok', remote: true %>
I don't see a setter for 'item' anywhere, which would prevent the link_to method from inferring its type and route.
What appears to be missing is a loop through the user's items, something along the lines of...
<h3>User's To-Do List</h3>
<% #user.items.each do |item| %>
<%= link_to "", item, method: :delete, class: 'glyphicon glyphicon-ok', remote: true %>
<%= render partial: 'items/item'%>
<% end %>
Note that this solution makes an assumption about the relationship between User and Item, specifically a has_many :items in the User.rb model.
My modal is working ( means when i click button it appears) but the form is not appearing, i have this modal in the index action so i have added <% #entries.each do |entry| %> and without it i am having undefined methodmodel_name' for NilClass:Class, any suggestions ?
<%= link_to "Assign", "#saturday-one", :class => "btn btn-primary", "data-toggle" => "modal" %>
<div class="modal hide fade" id="saturday-one">
<div class="modal-header">
<h3 id="myModalLabel">Time Table</h3>
</div>
<div class="modal-body">
<% #entries.each do |entry| %>
<%= simple_form_for(entry) do |f| %>
<%= f.association :subject, as: :select, label: 'Select Subject' %>
<%= f.association :employee, as: :select, label: 'Assign Employee' %>
<%= f.submit %>
<% end %>
<% end %>
</div>
<div class="modal-footer">
<button aria-hidden="true" class="btn btn-info" data-dismiss="modal">Done</button>
</div>
</div>
time_table_entries_controller.rb
class TimeTableEntriesController < ApplicationController
def index
#entries = TimeTableEntry.all
end
def show
#entry = TimeTableEntry.find(params[:id])
end
def new
#entry = TimeTableEntry.new
end
def create
#entry = TimeTableEntry.new(params[:time_table])
if #entry.save
redirect_to time_table_entries_url , notice: 'Time table Entries saved'
else
render :new
end
end
def edit
#entry = TimeTableEntry.find(params[:id])
end
def update
#entry = TimeTableEntry.find(params[:id])
if #entry.update_attributes(params[:time_table])
redirect_to time_table_entries_url, notice: 'TimeTableEntry Updated.'
else
render :edit
end
end
end
The following code does the following: If the user, voted up show him a delete vote form and a vote down form. If the user voted down, show him a vote up form and the delete vote form. Otherwise just show the vote up and vote down form (I omitted some of the code so the question doesn't get too long).
(scenario: user voted down):
posts_controller.rb:
def show
#post = Post.find(params[:id])
#replies = #post.replies.paginate(page: params[:page])
#reply = #post.replies.build
#vote = Vote.new
store_location
end
votes_controller.rb:
class VotesController < ApplicationController
before_filter :signed_in_user
def create
#votable = find_votable
# Destroy the vote first in case the user already voted
if already_voted?
#vote = #votable.votes.find_by_user_id(current_user.id)
#vote.destroy
end
#vote = #votable.votes.build(params[:vote])
#vote.user_id = current_user.id
#votable.save
respond_to do |format|
format.html { redirect_back }
format.js
end
end
def destroy
#votable = find_votable
#vote = #votable.votes.find_by_user_id(current_user.id)
#vote.destroy
#votable.reload
respond_to do |format|
format.html { redirect_back }
format.js
end
end
private
def find_votable
params.each do |name, value|
if name =~ /(.+)_id$/
return $1.classify.constantize.find(value)
end
end
nil
end
def already_voted?
#votable.votes.exists?(:user_id => current_user.id)
end
end
posts/vote_form
<div class="vote-form">
<% if #post.votes.exists?(:user_id => current_user.id) %>
<% if #post.votes.find_by_user_id(current_user.id).polarity == -1 %>
<%= form_for ([#post, #vote]), remote: true do |f| %>
<%= f.hidden_field :polarity, value: 1 %>
<div class="form-actions">
<%= button_tag type: :submit, class: "btn btn-small vote" do %>
<i class="icon-thumbs-down"></i> Vote up
<% end %>
</div>
<% end %>
<%= form_for ([#post, #post.votes.find_by_user_id(current_user.id)]),
method: :delete,
remote: true do |f| %>
<div class="form-actions">
<%= button_tag type: :submit, class: "btn btn-small btn-primary unvote" do %>
<i class="icon-thumbs-up"></i> Vote down
<% end %>
</div>
<% end %>
<% end %>
votes/create.js:
$('#<%= #votable.class.name.downcase %>-<%= #votable.id %> .vote-form').html(
"<%= escape_javascript(render('shared/delete_vote')) %>"
);
shared/_delete_vote.html.erb:
<% if #votable.votes.find_by_user_id(current_user.id).polarity == -1 %>
<%= form_for ([#votable, #votable.votes.new]), remote: true do |f| %>
<div class="form-actions">
<%= button_tag type: :submit, class: "vote-down btn btn-small" do %>
<i class="icon-thumbs-up"></i> Vote up
<% end %>
</div>
<% end %>
<%= form_for ([#votable, #vote]), method: :delete, remote: true do |f| %>
<div class="form-actions">
<%= button_tag type: :submit, class: "vote-up btn btn-small btn-primary" do %>
<i class="icon-thumbs-up"></i> Vote down
<% end %>
</div>
<% end %>
<% end %>
So, now everything works fine, except that I get this error when I click vote down, and then vote up right after (without refreshing the page):
ActionView::Template::Error (undefined method `polarity' for nil:NilClass):
1: <% if #votable.votes.find_by_user_id(current_user.id).polarity == 1 %>
2: <%= form_for ([#votable, #vote]), method: :delete, remote: true do |f| %>
What could be the problem?
EDIT:
I realized that the line in the error message is the problem (not #votable):
<% if #votable.votes.find_by_user_id(current_user.id).polarity == 1 %>
Strange, I thought it was the same as
<% if #post.votes.find_by_user_id(current_user.id).polarity == 1 %>
I think the problem is here:
def destroy
#votable = find_votable
#vote = #votable.votes.find_by_user_id(current_user.id)
#vote.destroy
#votable.reload
respond_to do |format|
format.html { redirect_back }
format.js
end
end
You destroy the vote for current user, so it can not be found inside view:
#votable.votes.find_by_user_id(current_user.id).polarity
That's why polarity is called on nil. You should reword the logic of your vote manipulations.
EDIT:
As the easiest solution, you may replace
if #votable.votes.find_by_user_id(current_user.id).polarity == -1
with
if #votable.votes.find_by_user_id(current_user.id).blank?