Rails withdraw_event_path 'undefined local method' - ruby-on-rails

I found a great solution to a problem of mine here
I've built it into my own project, but I can't seem to call the withdraw event.
show.html.erb
<p><strong>Attendees: </strong>
<ul>
<% for attendee in #event.users %>
<% if attendee.id == current_user.id %>
<li><strong><%= attendee.name %></strong>
<%= link_to 'Withdraw From Event', withdraw_event_path(#event.id), :method => :post, :class => 'btn btn-danger' %>
</li>
<% else %>
<li><%= attendee.username %></li>
<% end %>
<% end %>
</ul>
</p>
<p>
<%= link_to 'Attend Event', attend_event_path(#event.id), :method => :post %>
</p>
event_controller.rb
def attend
#event = Event.find(params[:id])
current_user.events << #event
redirect_to #event, notice: 'You are now attending this event'
end
def withdraw
event = Event.find(params[:id])
attendee = Attendee.find_by_user_id_and_event_id(current_user.id, event.id)
if attendee.blank?
redirect_to event
end
attendee.delete
redirect_to event, notice: 'You are no longer attending this event.'
end
when I call event->show I get this error
undefined local variable or method `withdraw_event_path' for #<#<Class:0x007fd5d575a910>:0x007fd5d22a72e0>
Any ideas why the path isn't working? I'm new to rails
THanks

you need to add withdraw to your routes, that will create the method withdraw_event_path
resources :events do
member do
post 'withdraw'
end
end

Related

Rails: Display pending friend requests in view

I am trying to to have the words Pedning Request show up next to a user in the user index if the current user has requested them or if the current user has been requested by them. I have a feeling something is wring with my erb, or I am just taking the wrong approach completely. When I click the add friend link, I want it to redirect back to the index page with the updated status of the request but it still displays the add friend link.
index.html.erb
Facebook Users:
<ul><% #users.each do |user| %>
<% if current_user == user || current_user.friends.include?(user) %>
<li><%= link_to user.email, user_path(user) %></li>
<% current_user.friend_requests.each do |request| %>
<% if request.friend_id == user.id %>
<li><%= link_to user.email, user_path(user) %>
| Pending Request</li>
<% end %>
<% end %>
<% else %>
<li><%= link_to user.email, user_path(user) %> |
<%= link_to "Add Friend", friend_requests_path(friend_id: user.id), method: :post %>
</li>
<% end %>
<% end %>
</ul>
<%= link_to 'Back to your profile', user_path(current_user) %>
<%= render 'shared/error_messages', object: current_user %>
<%= params.inspect %>
class FriendRequestsController < ApplicationController
before_action :set_friend_request, except: [:index, :create]
def index
#incoming = FriendRequest.where(friend: current_user)
#outgoing = current_user.friend_requests
end
def create
#user = User.find(current_user)
#friend = User.find(params[:friend_id])
#friend_request = current_user.friend_requests.new(friend_id: #friend.id)
if #friend_request.save
flash[:notice] = "Friend request sent!"
redirect_to users_path
else
flash[:notice] = "Unable to request friend"
redirect_to users_path
end
end
def update
friend_email = User.find(#friend_request.friend_id).email
#friend_request = FriendRequest.find_by_user_id_and_friend_id(params[:friend_id], params[:id])
if #friend_request.accept
flash[:notice] = "You and #{friend_email} are now friends!"
redirect_to user_path(current_user)
end
end
def destroy
if #friend_request.destroy
flash[:notice] = "Request Declined"
redirect_to user_path(current_user)
end
end
private
def set_friend_request
#friend_request = FriendRequest.find_by_user_id_and_friend_id(params[:friend_id], params[:id])
end
end
The if block starting with...
<% if request.friend_id == user.id %>
... is INSIDE the 'if' block starting with...
<% if current_user == user || current_user.friends.include?(user) %>
So basically the "Pending Request" can only be shown if the user is yourself (the current user) or if the user is already your friend. That doesn't make sense, of course.
Better to move the code after the first if's elseand you don't really need to loop through all the requests with each, just map the friend_id's
<ul>
<% #users.each do |user| %>
<% if current_user == user || current_user.friends.include?(user) %>
<li><%= link_to user.email, user_path(user) %></li>
<% else %>
<% if current_user.friend_requests.pluck(:friend_id).include? user.id %>
<li><%= link_to user.email, user_path(user) %>
| Pending Request</li>
<% else %>
<li><%= link_to user.email, user_path(user) %> |
<%= link_to "Add Friend", friend_requests_path(friend_id: user.id), method: :post %>
</li>
<% end %>
<% end %>
<% end %>
</ul>

Rails: validation on blog comments not working

I am trying to learn Rails by building a simple blog. I have made it possible to add comments with AJAX en I am now trying to validate the presence of a name and body in the comments. However, the validation is not working. When there are no errors the comment gets added like it should, but when I leave either 'name' or 'body' blank and try to add the comment, I get redirected to this weird flat HTML-version of the post I was trying to comment on (with a path like this: /posts/21/comments). I do not understand why this is happening instead of just the post page reappearing with an error message in it, and I would be very grateful to anyone that could help me out.
So here is the CommentsController:
class CommentsController < ApplicationController
def create
#post = Post.find(params[:post_id])
#comment = #post.comments.create(comment_params)
if #comment.errors.any?
respond_to do |format|
format.html { render #post }
format.js
end
else
respond_to do |format|
format.html { redirect_to #post }
format.js
end
end
end
def destroy
#post = Post.find(params[:post_id])
#comment = Comment.find(params[:id])
#comment.destroy
respond_to do |format|
format.html { redirect_to #post }
format.js
end
end
private
def comment_params
params.require(:comment).permit(:name, :body)
end
end
Model:
class Comment < ActiveRecord::Base
belongs_to :post
validates_presence_of :body, :name
end
And comment part of show.html.erb:
<section id="comment-section">
<div id="comments">
<h2>Reacties</h2>
<%= render partial: #post.comments.reverse %>
</div>
<%= form_for [#post, Comment.new], remote: true, authenticity_token: true do |f| %>
<% if #comment && #comment.errors.any? %>
<% #comment.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
<% end %>
<p>
<%= f.label :name, "Naam" %><br/>
<%= f.text_field :name %></br></br>
<%= f.label :body, "Reactie" %><br/>
<%= f.text_area :body %>
</p>
<p><%= f.submit "Verstuur" %></p>
<% end %>
</section>
And the _comment.html.erb partial:
<%= div_for comment do %>
<p>
<strong>
Posted <%= time_ago_in_words(comment.created_at) %> ago
</strong>
<br/>
<i><%= comment.name %>:</i>
<%= comment.body %>
</p>
<p>
<% if logged_in? %>
<%= button_to 'Delete', [comment.post, comment],
:method => :delete,
:class=> 'link-button',
remote: true,
data: { confirm: 'Are you sure?' }
%>
<% end %>
</p>
<% end %>
Finally, my routes.rb file:
Rails.application.routes.draw do
get 'static_pages/aboutme'
get 'static_pages/photos'
get 'sessions/new'
resources :posts do
resources :comments, only: [:create, :destroy]
end
get 'admin' => 'sessions#new'
post 'admin' => 'sessions#create'
delete 'logout' => 'sessions#destroy'
get '/overmij' => 'static_pages#aboutme'
get '/fotos' => 'static_pages#photos'
root 'posts#index'
end
The error is on this line format.html { render #post } That line renders the comments.index as they are nested with in posts so you get post/:id/comments. If you want to render a view (from another controller) you have to do it like this:
render template "posts/show"
or just
render "posts/show"
But the thing about rendering a view/template is that it will not set any variables needed, so you'll get a error like #variable is nil so you need to set the variables needed for post/show. Another thing you can do is redirect_to #post but the thing about redirect is that it will refresh the page and erase what the user had typed in the text box.
These are rails docs on rendering/redirecting
Usually I use flash to display my error messages, something like this should work
Controller
respond_to do |format|
format.html { flash[:notice] = #comment.errors, render #post }
format.js
end
View
<%if notice.present? %>
<div class="alert alert-danger" role="alert">
<% notice.each do |msg| %>
<li><%= msg %></li>
<% end %>
</div>
<% end %>

Heroku "Something Went Wrong" when trying to create a new form

I am trying to make a form that will create a new 'room'. However, when I push it to Heroku I am getting this error: 'We're sorry, but something went wrong.' I am using rails 4.1 and ruby 2.1.1. I am also using Heroku.
If it helps, I am kind of new to rails and am trying to port what I learned here to my new 'rooms' type.
This is my view/model/controller:
view: (app/views/rooms/index.html.erb)
<% if current_user %>
<h1>Create Room</h1>
<div class="Sign_Form">
<%= form_for(:room, :url => {:controller => 'rooms', :action => 'create'}) do |f| %>
<p> Created By:</br> <%= f.text_field :created_by%> </p>
<p> Name:</br> <%= f.text_field :name%> </p>
<p> Description:</br> <%= f.text_field :description%> </p>
<%= f.submit :Createroom %>
<% end %>
<% if #room.errors.any? %>
<ul class="Createroom_Errors">
<% for message_error in #room.errors.full_messages %>
<li>* <%= message_error %></li>
<% end %>
</ul>
<% end %>
</div>
<h1>All Rooms</h1>
<% if #rooms.nil? %>
Rooms is nil
<% else %>
<% #rooms.each do |room| %>
<%= room.name %>
<% end %>
<% end %>
<% else %>
<%= render 'welcome' %>
<% end %>
Model: (app/model/room.rb)
class Room < ActiveRecord::Base
class << self
end
end
Controller: (app/controllers/rooms_controller.rb)
class RoomsController < ApplicationController
def index
#rooms = Room.all
end
def new
#room = Room.new
end
def create
#room = Room.new(params[:room])
if #room.save
flash[:notice] = "Room has been created!"
flash[:color] = "valid"
else
flash[:notice] = "Room has not been created!"
flash[:color] = "invalid"
end
render new
end
end
Any help would be highly appreciated. Thanks ahead of time.
EDIT: When I run it on localhost it says: undefined method `errors' for nil:NilClass.

Error with Nested Model Edit page in Rails

I'm tying to perform an edit action on one of my nested models. I keep getting the following error "undefined method `model_name' for NilClass:Class"
I don't know what's going on. Any help?
Routes
resources :users, :except => [ :create, :new ] do
resources :store do
get "inbox", :on => :collection
get "openedmessages", :on => :collection
end
end
Store Actions
def edit
#store = current_user.store.id
end
def create
#store = current_user.store.new(params[:store])
end
def update
#stores = current_user.store.id
if #stores.update_attributes
flash[:success] = "Store has been updated"
render 'edit'
else
render 'edit'
end
end
View for Edit Action in Store
<ul class="storedashboard_header">
<li><%= link_to "Manage Gear", user_store_index_path(current_user) %></li>
<li><%= link_to "Store Appearance", edit_user_store_path(current_user, #store) %></li>
<li><%= link_to "Announcements", '#' %></li>
</ul>
<%= render "users/userdashboard_header" %>
<%= render "store/storemenu" %>
<div style="clear:both"></div>
<% flash.each do |name, msg| %>
<div class="alert alert-success">
<a class="close" data-dismiss="alert">×</a>
<%= msg %>
</div>
<% end %>
<div>
<%= simple_form_for #stores, :html => {:multipart => true, :class => 'form-horizontal'} do |f| %>
</br>
<div style="float: left;">
<%= f.input :storename %>
<%= f.input :storeimage %>
<%= f.input :storelogo %>
<%= f.button :submit, class: 'btn btn-large', style: 'margin-left: 40px;' %>
</div>
<% end %>
</div>
UPDATED
Changed my Controller to the following:
def edit
#store = Store.find(current_user.store.id)
end
def create
#store = current_user.store.new(params[:store])
end
def update
#store = Store.find(current_user.store.id)
if #store.update_attributes(params[:store])
flash[:success] = "Store has been updated"
render 'edit'
else
render 'edit'
end
end
New Error after Update
undefined method `store_path' for #<#:0x007fec93b97238>
FINAL FIX
Needed to fix the view...
<%= simple_form_for [current_user, #store], :html => {:multipart => true, :class => 'form-horizontal'} do |f| %>
if i understand your question properly:
#store needs to be an object for the model Store instead of just the id.
something like:
#store = Store.find(current_user.store.id) will return the object

Need help with implementing Railscast 198 in Rails 3

I have been trying to implement Ryan Bates Railscast 198 into rails 3 for like 4 days... at least at night if you know what I mean. Anyway, here is the code I have right now:
User controller actions (Devise setup to show the different states of approved):
def index
if params[:approved] == "false"
#users = User.find_all_by_approved(false)
elsif
#users = User.find_all_by_approved(true)
else
#users = User.all
end
end
def update
#user = User.find(params[:id])
respond_to do |format|
if #user.update_attributes(params[:user])
format.html { redirect_to root_path flash[:notice] = "User was successfully updated." }
else
format.html { render :action => "edit" }
end
end
end
def edit_individual
#users = User.find(params[:user_ids])
end
def update_individual
#users = User.update(params[:users].keys, params[:users].values).reject { |p| p.errors.empty? }
if #users.empty?
flash[:notice] = "Users updated"
redirect_to users_url
else
render :action => "edit_individual"
end
end
end
My User#index
<h1> Users</h1>
<%= link_to "All Users", :action => "index" %> |
<%= link_to "Users awaiting approval", :action => "index", :approved => "false"%>
|
<%= link_to "Approved Users", :action => "index", :approved => "true" %>
<%= form_tag edit_individual_users_path, :method => :put do %>
<table>
<tr>
<th>Email Address</th>
<th>Approved</th>
<th></th>
</tr>
<% for user in #users %>
<tr>
<td> <%= user.email %></td>
<td><%= check_box_tag user.id %></td>
<td> <%= link_to "Edit", edit_user_path(user) %></td>
</tr>
<% end %>
<p><%= submit_tag "Edit Checked" %></p>
</table>
<% end %>
And the User#edit_individual
<%= form_tag update_individual_users_path, :method => :put do %>
<% for user in #users %>
<%= fields_for "users[]", user do |f| %>
<h2><%=h user.name %></h2>
<p><%= check_box_tag user.id %></p>
<% end %>
<% end %>
<p><%= submit_tag "Submit" %></p>
<% end %>
routes.rb
devise_for :users
resources :users do
collection do
post :edit_individual
put :update_individual
end
end
end
So I handled the basic by googling: fields_for needs an "=" stuff like that. #index shows fine but if I check a checkbox and then hit the edit checked button I get the following error:
ActiveRecord::RecordNotFound in UsersController#update
Couldn't find User with id=edit_individual
Any ideas??? thanks so much
Please check your routes.rb and controller code, as it's quite a bit off from the code on Railscast 198's page: http://railscasts.com/episodes/198-edit-multiple-individually
It's best to just copy it in if you're new to rails and adjust for using users instead of products. Then go through it to try to understand what it does.

Resources