RecordNotFound Can't find Event without ID - ruby-on-rails

I am having a lot of trouble trying to pass an id from a model into a different controller. I've read similar posts and tried different solutions, but can't seem to pass the Event id into the Invitations controller.
UPDATE
The goal is that a user, while looking at an event they created, will click on an Invite link. This link needs to save the ID from the Event it came from so that Invitations can be associated with that event.
In my models, I for the Event model, I have 'has_many "invitations' and for the Invitation model I have 'belongs_to :events'
Here is my code.
show.html.erb within my Events folder:
<%= link_to 'Invite guests', invitations_path(:event => #event.id) %>
This link maps to 'invitations#new':
<% provide(:title, 'Invite Guests') %>
<h1>Invite your guests</h1>
<%= form_for(#invitation) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.label :name %>
<%= f.text_field :name, :placeholder => "Name" %> <br>
<%= f.label :email %>
<%= f.text_field :email, :placeholder => "Email" %> <br>
<%= f.submit "Send" %>
InvitationsController:
def index
end
def new
#invitation = Invitation.new
end
def create
user = current_user.events.find(params[:event])
#invitation = user.invitations.build(params[:invitation])
if #invitation.save
flash[:success] = "Invitations sent!"
redirect_to user
else
render '/home'
end
end
I know that if I replace:
user = current_user.events.find(params[:event])
with:
user = current_user.events.find(1)
Routes:
resources :users
resources :sessions, only: [:new, :create, :destroy]
resources :events, only: [:show, :create, :destroy]
resources :invitations, only: [:new, :create]
root to: '/home'
match '/signup', to: 'users#new'
match '/signin', to: 'sessions#new'
match '/signout', to: 'sessions#destroy', via: :delete
match '/events', to: 'events#new'
match '/invitations', to: 'invitations#new'
Everything works fine, but of course, this is not suitable since I am hard coding the Event ID. I am pretty new to RoR (about 2 months of experience) so there may be a more efficient way to do this. So any help would be much appreciated.

<%= link_to 'Invite guests', invitations_path(:event => #event.id) %>
Goes to:
def index
Not to:
def create
If you want to go to create do:
<%= link_to 'Invite guests', invitations_path(:event => #event.id), method: :post %>

Related

No route matches [POST] "/stories/id/invites"

All of the sudden I am getting this error even though it has been working for a while:
No route matches [POST] “/stories/id/invites”
Routes:
story_invites_path GET /stories/:story_id/invites(.:format) invites#index
routes.rb
resources :stories do
match '/stories/:id/invite', to: 'invite#show', via: 'get'
resources :invites , only: [:index, :show, :destroy ]
end
invites/index view
<%= form_for #invite , :url => story_invites_path do |f2| %>
<%= f2.text_field :user_id, :value => user.id , :class => 'number_field' %>
<%= f2.submit 'Send', class: 'btn btn-primary' %>
<% end %>
invites controller
def create
#invite = #story.invites.new(invite_params)
if #invite.save
flash[:success] = 'The user was invited!'
redirect_to(:back)
else
render :new
end
end
How do I add a post method to my invites path?
You have all sort of icky things...
This:
resources :stories do
match '/stories/:id/invite', to: 'invite#show', via: 'get'
resources :invites , only: [:index, :show, :destroy ]
end
Should be:
resources :stories do
resources :invites
end
Which will give you:
story_invites GET /stories/:story_id/invites(.:format) invites#index
POST /stories/:story_id/invites(.:format) invites#create
new_story_invite GET /stories/:story_id/invites/new(.:format) invites#new
edit_story_invite GET /stories/:story_id/invites/:id/edit(.:format) invites#edit
story_invite GET /stories/:story_id/invites/:id(.:format) invites#show
PATCH /stories/:story_id/invites/:id(.:format) invites#update
PUT /stories/:story_id/invites/:id(.:format) invites#update
DELETE /stories/:story_id/invites/:id(.:format) invites#destroy
stories GET /stories(.:format) stories#index
POST /stories(.:format) stories#create
new_story GET /stories/new(.:format) stories#new
edit_story GET /stories/:id/edit(.:format) stories#edit
story GET /stories/:id(.:format) stories#show
PATCH /stories/:id(.:format) stories#update
PUT /stories/:id(.:format) stories#update
DELETE /stories/:id(.:format) stories#destroy
If you really want to limit your invite routes, fine. But right now, you're limiting out create. Which is really why you're getting:
No route matches [POST] “/stories/id/invites”
Because you TOLD rails you didn't want a create path. Rails is dumb that way. Does what you tell it. Not what you mean.
Also, this:
match '/stories/:id/invite', to: 'invite#show', via: 'get'
Is just really full of badness and banana slugs. Please don't do that. To yourself. Or to us.
This:
<%= form_for #invite , :url => story_invites_path do |f2| %>
<%= f2.text_field :user_id, :value => user.id , :class => 'number_field' %>
<%= f2.submit 'Send', class: 'btn btn-primary' %>
<% end %>
probably needs to look more like this:
<%= form_for :invite, story_invites_path(story) do |f2| %>
<%= f2.hidden_field :invite, :user_id, value: #user.id %>
<%= f2.submit 'Send', class: 'btn btn-primary' %>
<% end %>
Use :invite instead of #invite because you're in index and you probably don't have an #invite. If you do, fine. But rails can use the symbol to infer the correct fields.
You're going to have to look up that hidden_field method, because I'm doing this from memory.
And I don't know where you're going to get story from because you're in your index method. But, you can do something like #stories = Story.all. In which case this whole block will need to wrapped in something like:
<% #stories.each do |story| %>
<%= story.name %>
<%= form_for :invite, story_invites_path(story) do |f2| %>
<%= f2.hidden_field :invite, :user_id, value: #user.id %>
<%= f2.submit 'Send', class: 'btn btn-primary' %>
<% end %>
<% end %>
Man, this makes me remember why I dislike erb. If you were doing this in HAML, it would be pretty, like unicorns and rainbows:
- #stories.each do |story|
.story-container{id: "story-id-#{story.id}"}
.story-name
= story.name
.story-invite-container
= form_for :invite, story_invites_path(story) do |f2|
= f2.hidden_field :invite, :user_id, value: #user.id
= f2.submit 'Send', class: 'btn btn-primary'
Don't you like unicorns and rainbows? Look at all those beautiful divs with ids and classes just waiting to be dressed up with your butt-kicking, mad-ninja-skills CSS (display: inline-block, anyone?). (Please tell me you're using SASS. Please?)
Now, on submit, your params are going to look something like (I'm making up the story_id and 'user_id` values):
{..., story_id: 4, invite: {user_id: 1}, ...}
I assume in invites_controller, you have something like:
class InvitesController < ActionController::Base
def index
...
#stories = Story.all
...
end
def create
#story = Story.find_by(id: params[:story_id])
#invite = #story.invites.new(invite_params)
if #invite.save
flash[:success] = 'The user was invited!'
redirect_to(:back)
else
render :new
end
end
def invite_params
params.require(:invite).permit(:user_id)
end
end
And that all ought to hang together.
For the life of me, I don't know why you redirect_to :new, but hey whatever floats your boat. (Are sure you don't want to redirect_to stories_path or maybe redirect_to story_path?)
Update your routes.rb to include create in your resources :invites, like this:
resources :stories do
match '/stories/:id/invite', to: 'invite#show', via: 'get'
resources :invites , only: [:index, :show, :destroy, :create ]
end
That change will generate this new route:
story_invites POST /stories/:story_id/invites(.:format) invites#create

NoMethodError, undefined method `permits_path' for #<#<Class:0xbbb3ed0>:0xbbb34b0>

I'm new to ROR. I'm trying to create a page for parking permit application. I encountered this problem
I couldn't find the problem. Or maybe i missed something. Any help is appreciated.
This is my permit_controller.rb
class PermitController < ApplicationController
before_action :set_permit, only: [:show, :destroy]
def index
#permit = Permit.all
end
def new
#permit = Permit.new
end
def create
#permit = Permit.new(user_params)
if #permit.save
redirect_to root_path
else
flash[:success] = "Welcome to your profile!"
end
end
def destroy
end
def show
#permit = Permit.find(params[:id])
end
private
# Use callbacks to share common setup or constraints between actions.
def set_permit
#permit = Permit.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def permit_params
params.require(:permit).permit(:vehicle_type, :name, :studentid, :department, :carplate, :duration,:permitstart,:permitend)
end
end
This is my permit/new.html.erb
<% provide(:title, 'New Permit') %>
<h1>Permit Application</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_for(#permit) do |f| %>
<%= render 'shared/error_messages' %>
<%= f.label :"Vehicle Type" %>
<%= f.text_field :vehicle_type, class: 'form-control' %>
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control' %>
<%= f.label :"Student ID" %>
<%= f.text_field :studentid, class: 'form-control' %>
<%= f.label :department %>
<%= f.text_field :department, class: 'form-control' %>
<%= f.label :"Car Plate" %>
<%= f.text_field :carplate, class: 'form-control' %>
<%= f.submit "Confirm", class: "btn btn-primary" %>
<% end %>
</div>
</div>
This is my route.rb
Rails.application.routes.draw do
resources :users
resources :permit
get 'permit/destroy'
get 'permit/show'
root 'static_pages#home'
get 'homepage/index'
post 'permit' => 'permit#create'
get 'permitapplication' => 'permit#new'
get 'adminlogin' => 'admin_controller#index'
get 'contact'=> 'static_pages#contact'
get 'about' => 'static_pages#about'
get 'signup' => 'users#new'
get 'help' => 'static_pages#help'
post 'users' => 'users#create'
get 'login' => 'sessions#new' #Page for a new session
post 'login' => 'sessions#create' #Create a new session
delete 'logout'=>'sessions#destroy' #Delete a session
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
Instead resources :permit use resources :permits.
The biggest issue here is you don't have permit/new in your routes.rb file.
As has already been suggested, it might be better for you to leverage rails
with a resources call
in routes.rb
resources :permits
and remove lines
get 'permit/destroy'
get 'permit/show'
etc.
I'll attempt to consolidate our various answers and comments.
To solve your current problem, in config/routes.rb, change resources :permit to resources :permits. This exposes all seven RESTful routes for use in your application. (This also makes obsolete the custom permit routes, unless you're explicitly calling them from within their respective forms.) Information about RESTful routes/resources here: http://guides.rubyonrails.org/routing.html#crud-verbs-and-actions
Why is this valuable?
It's how your application knows to use controller actions in combination with views (and therefore forms). Say you have an edit action in your permits controller and app/views/permits/edit.html.erb has a form. Within this page's edit form, you need only have form_for #permit and Rails does all the rest. It knows you're using this particular route. I recommend you read about routing within Rails.
Please keep in mind Ruby on Rails has been carefully crafted to make things easy for you, the developer.

Want to edit/PUT/PATCH but error says "No route matches [POST]"

I'm building my second-ever basic Ruby on Rails application and having fun doing it, but have gotten stuck at precisely the same place that gave me trouble (and was never solved) on my last effort: the PUT or PATCH request.
My application has two models: entries and users. A logged-in user should be able to edit only those entries that were originally created by that user.
CONTROLLER
class EntriesController < ApplicationController
# authenticate user (Devise)
before_action :authenticate_user!, :except => [:index, :show]
# set entry upon page load
before_action :set_entry, :only => [:show, :edit, :update, :destroy]
# GET request - display all entries
def index
#all_entries = Entry.all
end
# GET request - display an individual entry
def show
# nothing required here because entry identified with before_action :set_entry on line 2 above
end
# GET request - access form to create a new entry
def new
#entry = Entry.new
#user = User.find(current_user[:id])
end
# GET request - access form to update an existing entry
def edit
if #entry[:user_id] != current_user[:id]
redirect_to root_path
else
redirect_to edit_entry_path
end
end
# POST request - make a new entry/save new data into db
def create
user = current_user[:id]
Entry.create({
entry_title: params[:entry][:entry_title],
book_title: params[:entry][:book_title],
text: params[:entry][:text],
img_url: params[:entry][:img_url],
tag: params[:entry][:tag],
created_at: params[:entry][:created_at],
user_id: user
})
redirect_to entries_path
end
# PUT request - save changes to an existing entry
def update
if #entry.update(entry_params)
redirect_to entry_path
else
render :new
end
end
# DELETE request - delete an existing entry from db
def destroy
#entry.destroy
redirect_to entries_path
end
private
def set_entry
#entry = Entry.find(params[:id])
end
def entry_params
params.require(:entry).permit(:email, :text, :tag)
end
end
VIEW (show.html.erb - shows a single entry and includes links allowing the logged-in user who originally authored the entry to edit or delete it)
<h3>Selected Entry</h3>
<div class="row">
<div class="col-md-2"></div>
<div class="col-md-6">
<div>Entry title: <%= #entry.entry_title %></div>
<div>Book title: <%= #entry.book_title %></div>
<div>Text: <%= #entry.text %></div>
</div>
<div class="col-md-4">
<div><%= #entry.created_at.strftime("%b %d, %Y") %></div>
<div>Submitted by: <i><%= #entry.user.email %></i></div>
<div>File under: <i><%= #entry.tag %></i></div>
<% if current_user %>
<%= link_to 'Edit', #entry, :method => 'update' %>
<%= link_to 'Delete', #entry, :method => 'delete' %>
<% end %>
</div>
</div>
ROUTES.RB - At first my routes were the commented-out lines, but then I had a thought that was either madness or sudden realization - should only the GET routes lead with "get"? So that's the non-commented-out attempt you see. Somehow the app works (except for the issue at hand) both ways.
In researching I've come across routes defined using a much more elaborate syntax than that I'm using here. I've been unable to figure out whether a given way of doing things is different convention, outdated, or just inadequate to the task.
Rails.application.routes.draw do
devise_for :users
resources :entries
# root 'entries#index'
# get '/entries' => 'entries#index'
# get '/users' => 'users#index'
# get '/entries/:id' => 'entries#show'
# get '/entries/:id' => 'entries#update'
# get '/entries/new' => 'entries#new'
# get '/entries/:id/edit' => 'entries#edit'
# get '/users/:id' => 'users#show'
# get '/about' => 'pages#index'
root 'entries#index'
get '/entries' => 'entries#index'
get '/entries/new' => 'entries#new'
post '/entries' => 'entries#create'
get '/entries/:id' => 'entries#show'
get '/entries/:id/edit' => 'entries#edit'
put '/entries/:id' => 'entries#update'
delete '/entries/:id' => 'entries#destroy'
get '/users' => 'users#index'
get '/users/:id' => 'users#show'
get '/about' => 'pages#index'
end
Thanks in advance for any insight. If additional context is needed I'm happy to provide.
Edited to add:
PARTIAL (_form.html.erb)
<div class="row">
<div class="col-md-2"></div>
<div class="col-md-6" id="form-container">
<%= form_for #entry do |form| %>
<br>
<%= form.text_field :entry_title, :size => 59, :placeholder => "Entry Title"%>
<br><br>
<%= form.text_field :book_title, :size => 59, :placeholder => "Book Title"%>
<br><br>
<%= form.text_field :img_url, :size => 59, :placeholder => "Image URL"%>
<br><br>
<%= form.text_area :text, :placeholder => "Text" %>
<br><br>
<%= form.text_field :tag, :placeholder => "Tag" %>
<br><br>
<%= form.submit %>
<% end %>
</div>
<div class="col-md-4"></div>
</div>
To edit a record you
first, should use a GET request to get the edit form
second, should submit that form using a PUT/PATCH request
To get to the edit form you should link to the edit path for your entry
<%= link_to 'Edit', edit_entry_path(#entry) %>
The Rails form helpers will automatically set the form to submit with the proper method, PUT OR PATCH.
:method in link_to helpers refers to HTML verb (get, post, etc), while controllers methods naming convention is action.
link_to
You need something as
<%= link_to 'Edit', #entry, :method => 'put' %>
or
<%= link_to 'Edit', #entry, :action => 'update' %>
At a glance you are trying to post with the edit link. Remember new/edit are get methods to render form, so just just delete method part in your links. Like from
<%= link_to 'Edit', #entry, :method => 'update' %>
to
<%= link_to 'Edit', edit_entry_path(#entry) %>
I'm building my second-ever basic Ruby on Rails application
Congrats! You need at least 3 more before it all starts to make sense
To add to the existing answers, you'll be best looking at the resources directive to clean the routes up:
#config/routes.rb
root 'entries#index'
devise_for :users
resources :entries
resources :pages, only: [:index], path_names: { index: "about" }
resources :users, only: [:index,:show]
--
A logged-in user should be able to edit only those entries that were originally created by that user.
This is known as authorization.
Authentication = is user logged in?
Authorization = can user do this?
Although people confuse Devise with being able to handle authorization, it only handles authentication. Whilst you have a simple implementation of this in your controller, you should check out either the CanCanCan or Pundit gems:
#Gemfile
gem "cancancan"
#app/models/ability.rb
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
can :manage, Post, user_id: user.id
end
end
#app/controllers/entries_controller.rb
class EntriesController < ApplicationController
def edit
authorize! :edit, #entry
end
end
--
Finally, to answer your question directly, you're calling the update method (which doesn't exist) to access the edit view:
<% if current_user %>
<%= link_to 'Edit', #entry, :method => 'update' %>
<%= link_to 'Delete', #entry, :method => 'delete' %>
<% end %>
You should read up about http verbs - this is what the "method" option invokes with the link. As mentioned above, you don't need to set the method for edit as it uses GET. Update uses put/patch, which I can explain later.
A much better way to achieve what you want would be the following:
<%= link_to "Edit", edit_entry_path(#entry) if can? :edit, #entry %>
<%= link_to "Delete", #entry, method: :delete, if can? :destroy, #entry %>
The above uses the CanCanCan authorization method can?

undefined local variable or method `subjects_path'

I want to search text from mysql db table .
view page:
<% form_tag subjects_path, :method => :get do %>
<p>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "Search", :name => nil %>
</p>
<% end %>
controller code:
before_action :confirm_logged_in
def index
#subjects=Subject.sorted
#subjects = Subject.search params[:search]
end'
Routes used:
root 'demo#index'
get 'admin', :to=> "access#index"
match ':controller(/:action(/:id))' ,:via=>[:get,:post]
i am waiting for your answer.
in routes.rb you need to define the subjects
resources :subjects, only: [:index]
You've not specified any named routes so subjects_path doesn't exist.

Virtual Attributes: No route matches {:controller=>"phone", :action=>"new"}

I have a controller "find_numbers", which I'm using to submit a form to the Twilio API. Before it submits though, I'd like to validate against two form fields, which aren't in the data model for this controller. The fields are :name, and :original_number
So, in my find_numbers model, I added attr_accessor :name, attr_accessor :originial number to run a validates command under it.
After doing that and submitting the form as invalid, I get the error :
Routing Error
No route matches {:controller=>"phone", :action=>"new"}
Try running rake routes for more information on available routes.
I'm not sure why it says there's no roots, but I'm not sure why it's accessing that anyways. I want it to POST to find_numbers
The find_numbers/new template
<%= form_tag("/find_numbers", :method => "post", :id => "new_user" ) do %>
<%= render 'shared/error_messages' %>
<%= label_tag(:name, "What Are You Tracking?") %>
<%= text_field_tag(:name) %>
<%= label_tag(:original_number, "Your Orginal Number") %>
<%= text_field_tag(:original_number) %>
<%= label_tag(:in_postal_code, "Near US postal code (e.g. 94117):") %>
<%= text_field_tag(:in_postal_code) %>
<%= label_tag(:near_number, "Near this other number (e.g. +4156562345)") %>
<%= text_field_tag(:near_number) %>
<%= label_tag(:contains, "Matching this pattern (e.g. 415***EPIC):") %>
<%= text_field_tag(:contains) %>
<%= submit_tag("Search", :class => "btn btn-large btn-primary") %>
<% end %>
here's my find_number model
class FindNumber < ActiveRecord::Base
attr_accessor :name
attr_accessor :original_number
validates :name, presence: true
validates :original_number, presence: true
end
Here's my Find_number controller
class FindNumbersController < ApplicationController
def new
#user = current_user
end
def create
#user = current_user
client = Twilio::REST::Client.new(#user.twilio_account_sid, #user.twilio_auth_token)
search_params = {}
%w[in_postal_code near_number contains].each do |p|
search_params[p] = params[p] unless params[p].nil? || params[p].empty?
end
local_numbers = client.account.available_phone_numbers.get('US').local
#numbers = local_numbers.list(search_params)
unless #numbers.empty?
render 'find_numbers/show'
else
flash.now[:error] = "Sorry, We Couldn't Find Any Numbers That Matched Your Search! Maybe Something Simpler?"
render 'find_numbers/new'
end
end
def show
end
end
Any thoughts on accomplishing this would be greatly appreciated!
Edit
Routes.rb file
Dct::Application.routes.draw do
resources :users
resources :sessions, only: [:new, :create, :destroy]
resources :phones, only: [:new, :create, :destroy]
resources :find_numbers, only: [:new, :create, :destroy]
match '/find_numbers', to: 'find_numbers#new'
match '/signup', to: 'users#new'
match '/login', to: 'sessions#new'
match '/signout', to: 'sessions#destroy', via: :delete
root to: 'static_pages#home'
match '/product_demo', to: 'static_pages#product_demo'
match '/pricing', to: 'plans#index'
match '/contact', to: 'static_pages#contact'
Edit
Here is the server log, of what happened when I hit submit
http://stepanp.com/railserror.jpg
Also, here's the find_numbers/show view
From what you've posted, the only other thing that looks suspicious to me is that you presumably have a PhonesController (plural) since you've declared resources :phones, but the routing error seems to occur because it is looking for a PhoneController (singular).

Resources