Ruby on rails application have two model User and Location
User model
belongs_to :location
Location model
has_many :users
routes.rb
devise_for :users
resources :users
This view in location show page
<% #location.users.each do |locuser| %>
<%= link_to locuser.email, user_path %><br>
<% end %>
Error is Couldn't find User with 'id'
This my Users Controller
def show
#user = User.find(params[:id])
end
I added <%= link_to locuser.email, current_user %>
it also not working.
I am considering you are not using devise routes. where no need to pass user object to routes. In your show action you do need id so I am passing user object for show path. If this is not the case run rake routes | grep user and paste log here
it should be user_path(locuser)
try change :
<% #location.users.each do |locuser| %>
<%= link_to locuser.email, user_path(locuser) %><br>
<% end %>
or
<% #location.users.each do |locuser| %>
<%= link_to locuser.email, locuser %><br>
<% end %>
Related
Doing nested routes for the first time and I cannot figure out the link_to paths for the nested routes that I have. Using rails scaffold for each
resources :venues do
resources :events
end
I edited to have the following in the index.html.erb of the venue model
<%= link_to 'Events', venue_events_path(venue) %>
Which brings me to the correct index.html.erb of the events model (venues/1/events)
But I just can't seem to figure out the correct link_to path on the show page of event to bring me back to venues/1/events
With the default scaffold, its
<%= link_to 'Back', events_path %>
I have tried different paths like venue_events_path(venue) but rails keeps saying that it cannot find venue without an ID.
I am assuming that is because clicking on the default show link brings me to localhost:3000/events/1 instead of localhost:3000/venues/1/events/1
What would be the correct paths for nested attributes besides the difficulty that I am facing?
For nested routes I would use the following setup:
# routes.rb
resources :venues do
resources :events
end
# venues controller
class VenuesController < ApplicationController
def index
#venues = Venue.all
end
def show
#venue = Venue.find(params[:id])
end
end
# venues index.html.erb
<% #venues.each do |venue| %>
<%= link_to 'Venue', venue_path(venue) %>
<% end %>
# venues show.html.erb
# link to the events index page from the current venue
<%= link_to 'Events', venue_events_path(#venue) %>
# link to each individual event from the current venue
<% #venue.events.each do |event| %>
<%= link_to 'Event', venue_event_path(#venue, event)
<% end %>
# events controller
class EventsController < ApplicationController
def index
#venue = Venue.find(params[:venue_id])
#events = #venue.events
end
def show
#event = Event.find(params[:id])
end
end
# events index.html.erb
# link back to venue
<%= link_to 'Venue', venue_path(#venue) %>
# link to each event
<% #events.each do |event| %>
<%= link_to 'Event', venue_event_path(event.venue, event) %>
<% end %>
# events show.html.erb
# link back to events index
<%= link_to 'Events', venue_events_path(#event.venue) %>
# link back to venue show
<%= link_to 'Venue', venue_path(#event.venue) %>
Keep in mind that this will only work if your events have an venue id. You said you have in your event model: belongs_to :venue, optional: true the optional true make the venue_id not required for an event. If that is what you want then nested routes doesn't really makes sense, because an NOT nested event is not going to be linked nested.
So I'm getting the error stated in the title. What code would I have to write in my Postscontroller to fix this? I'm not sure what I would have to do here, would I have to define rsvp in my post controller? If thats the case how would I go about doing that?
class RsvpController < ApplicationController
def create
rsvp = current_user.rsvps.build({post_id: params[:id]})
if rsvp.save
end
end
end
Show.html.erb
<p>
<strong>Date:</strong>
<%= #post.date %>
</p>
<p>where:<%=#post.longitude %>, <%=#post.latitude%></p>
<p>
<strong>Name:</strong>
<%= #post.name %>
</p>
<p>
<strong>User_id:</strong>
<%= #post.user_id %>
</p>
<p>
<strong>Description:</strong>
<%= #post.description %>
</p>
<% if current_user == #post.user %>
<%= link_to 'Edit', edit_post_path(#post) %> |
<%end%>
<%= link_to 'Back', posts_path %>
<%= button_to "Rsvp now", rsvp_post_path(#post), class: "btn btn-primary" %>
routes.rb
Rails.application.routes.draw do
mount RailsAdmin::Engine => '/admin', as: 'rails_admin'
resources :posts
devise_for :users
root 'home#index'
get 'home/ruby_meetup'
resources :posts do
post 'rsvp', on: :member
end
Also I want it so it shows the list of people who already rsvped for the event. How would I go about doing that? I would appreciate some help as I'm still learning rails and this is my first project.
By the following line, you define the route:
resources :posts do
post 'rsvp', on: :member
end
By this line you're requesting this route:
To process the request, you need a controller action rsvp, which actually the error states.
Thus, just define the action (method) and process the request:
class RsvpController < ApplicationController
def create
rsvp = current_user.rsvps.build({post_id: params[:id]})
if rsvp.save
end
end
def rsvp
# process the request here...
end
end
This app has the following models:
Farm (has_many :crops)
Crop (belongs_to :farm, has_many :issues)
Issue (belongs_to :crop)
Here are the routes:
resources :farms do
resources :crops do
resources :issues
end
end
I want a user to be able to create a new "issue" from the Farm#show page that lists all the farm's crops. Here is the form that is causing the error on the Farm#show page:
undefined method `crop_issues_path' for #<#:0x007fa814a3cc30>
#from the show action on the controller:
##farm = Farm.find(params[:id])
##crops = #farm.crops
<% #crops.each do |crop| %>
<%= crop.id %>
<%= form_for([crop, crop.issues.build]) do |f| %>
<%= f.select(:issue_type, options_for_select([['mold'], ['pests'], ['dehydration'], ['other']])) %>
<%= f.text_area :notes %><br>
<%= f.submit "New Issue", :class => "button" %>
<% end %>
<% end %>
My create action on issues controller:
def create
#crop = Crop.find(params[:crop_id])
#issues = #crop.issues.create(params[:issue].permit(:issue_type, :notes, :crop_id))
redirect_to :back
end
I have used nearly identical code when the crops and issues were not nested under farms, and it works. I believe the issue is because of the nesting, but cannot figure out a solution.
I think your problem is with the object you're binging the form to. It should be #farm, as you're in the #farms show action.
I modified it to this:
<% #crops.each do |crop| %>
<%= crop.id %>
<%= form_for([#farm, crop, crop.issues.build]) do |f| %>
<%= f.text_area :notes %><br>
<%= f.submit "New Issue", :class => "button" %>
<% end %>
<% end %>
with my controller like this:
class FarmsController < ApplicationController
def index
end
def show
#farm = Farm.find_by_id(params[:id])
#crops = #farm.try(:crops)
end
end
Im writing a game on rails, and am trying to allow a user to create their mine (its a mining game).
I have a table for the users, and a table for mines.
Each user has a ref. ID on their entry, pointing to their mine's ID in the mine table.
I'm getting an error when I try to visit /users/1/mines/new.
undefined method `mines_path'
I can't figure out why.
form in New:
<%= form_for [#mine] do |f| %>
<%= f.label :name %>
<%= f.text_field :name %><br>
<p>Depth: <%= #mine.depth %></p>
<%= f.submit "Submit", id: "submit" %>
<% end %>
Controller:
def new
#user = User.find(params[:user_id])
#mine = #user.mines.new
end
def create
#mine = #user.mines.create(mine_params)
if #mine.save
redirect_to users_mines_path
else
render new_mines_path
end
end
routes:
root 'welcome#index'
resources :sessions, only: [:create]
resources :users do
resources :mines
end
resources :tools, only: [:create]
How can I create a new mine THROUGH the user? Am I doing this correctly in my controller?
Thanks!
In your routes you have mines nested inside users so you need to change your form to something like this:
<%= form_for [#user,#mine] do |f| %>
<%= f.label :name %>
<%= f.text_field :name %><br>
<p>Depth: <%= #mine.depth %></p>
<%= f.submit "Submit", id: "submit" %>
<% end %>
OR
You can specify url option with your path:
<%= form_for #mine, url: user_mines_path(#user) do |f| %>
<%= f.label :name %>
<%= f.text_field :name %><br>
<p>Depth: <%= #mine.depth %></p>
<%= f.submit "Submit", id: "submit" %>
<% end %>
For details on forms refer to Form Helpers
Also as #Vimsha pointed out in your controller you need to use .new instead of .create as create will initialize and save your your mine.
def create
#mine = #user.mines.new(mine_params)
if #mine.save
redirect_to user_mines_path
else
render new_user_mine_path
end
end
#user.mines.create will create the mine. So use #user.mines.new
named route for mine index will be user_mines_path
named route for mine show will be user_mine_path(#mine)
named route for new mine will be new_user_mine_path
Contoller:
def create
#mine = #user.mines.new(mine_params)
if #mine.save
redirect_to user_mines_path
else
render new_user_mine_path
end
end
I am newbie to ruby on rails. I am getting this error. I have followed this tutorial http://www.codelearn.org/ruby-on-rails-tutorial/forms-form_tag-params-attr_accessible-model-validation
for the form posting. But when I click on submit i was getting an error
this is my
controller
class CompanyratingController < ApplicationController
def index
#companies = Companyrating.all
end
def add
#companies.create(:companies => params[:name, :place, :rate, :rank])
#redirect_to :action => 'index'
#companies = Companyrating.new(params[:name])
if #companies.save
flash[:success] = "Welcome to My Space!"
redirect_to root_url
end
end
end
this is modal
class Companyrating < ActiveRecord::Base
attr_accessible :name, :place, :rate, :rank
end
this is my routes file
get "companyrating/index"
match "companyrating/add" => "todos#add", :via => :post
my index file
<title>Shared Todo App </title>
<h1>Shared Todo App</h1>
<p>All your todos here</p>
<ul><li> <% #companies.each do |t| %>
<li> <%= t.companies_name %> </li>
<li> <%= t.companies_place %> </li>
<li> <%= t.companies_rate%> </li>
<li> <%= t.companies_rank %> </li>
<% end %>
</li></ul>
<%= form_for("#companies/add", :method=>"post") do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :place %>
<%= f.text_field :place %>
<%= f.label :rate %>
<%= f.text_field :rate %>
<%= f.label :rank %>
<%= f.text_field :rank %>
<%= f.label :user_id%>
<%= f.text_field :user_id %>
<%= f.submit "Save changes", class: "btn btn-large btn-primary" %>
<% end %>
This was my error: No route matches [POST] "/companyrating/index"
can anyone help me in solving this error
in controller:
def new
#companyrating = Companyrating.new
end
def create
#companies = Companyrating.new(params[:companyrating])
if #companies.save
flash[:success] = "Welcome to My Space!"
redirect_to root_url
else
flash[:error] = "Can't create companyrating."
render 'new'
end
end
in routes.rb:
resources :companyrating
in form:
<%= form_for(#companyrating, method: :post) do |f| %>
The problem you're having is two-fold - with your routes and controller actions
I know Monk_Code gave an answer, but since you're new, I'll explain how it all works for you, with the goal of helping you understand the system a bit better:
Routes
Your first issue is to do with your routes
Rails has done an amazing job of creating great routing structures, and the core of this is the idea of resourceful routes
By using the following code, your Rails app creates a series of 7 routes which Rails uses to send "default" traffic to your controller actions:
#config/routes.rb
resources :companyratings
This routing structure creates the following routes in your app:
new [GET]
index [GET]
create [POST]
edit [GET]
update [POST]
destroy [DELETE]
show [GET]
All of these routes take directed traffic, and routes it to the relevant controller action. This means that if you send a user to /companyratings/, it's going to load the index action, likewise /companyratings/15 will show the show action in the controller
On top of this, you also need to know what the HTTP "verb" does. This is a key principle which Rails uses to route your traffic accordingly. The "verb" in your request is the type of request that's sent, and is dependent on the browser
As you can see from the list above, every route has an associated HTTP verb. The reason why this is important is because if you send a [GET] request to a route which only works with the [DELETE] verb, you're going to get a problem, hence why you're seeing errors when you send a [POST] request to your index action
You should read the Rails tutorial on this, as you can either fix the issue by sending the correct HTTP verb (using :method => :get), or specify the [POST] verb in your index action route
Controller Actions
Controller actions are the function defined in your controller, which are loaded when you run a particular request in Rails
The default index actions are listed above, but you can also have any others you like, as long as you provide the correct routes. Your problem is that you've just used the add action, where you should have used the create action:
class CompanyratingController < ApplicationController
def index
#companies = Companyrating.all
end
def new
#companyrating = Companyrating.new
end
def create
#companies = Companyrating.new(new_company_rating)
if #companies.save
flash[:success] = "Welcome to My Space!"
redirect_to root_url
end
end
private
def new_company_rating
params.require(:company_rating).permit(:variables, :listed, :here)
end
end