How to contruct 'new' in assciated controller in rails 3.1 - ruby-on-rails

I have two models in rails 3.1 app: lease_booking and lease_log. Lease_booking has_many lease_logs and lease_log belongs_to lease_booking. In routes.rb the association is:
resources :lease_bookings do
resources :lease_logs
end
In lease_booking show.html.erb, the path to create a new lease log is:
<%= link_to "new Log", new_lease_booking_lease_log_path(#lease_booking) %>
The 'new' code in lease_log controller is:
def new
#lease_log = LeaseBooking.find(params[:id]).lease_log.new()
end
However there is an error for lease_log controller 'new' after clicking 'new log':
Couldn't find LeaseBooking without an ID
It seems that the id (should be 1) of lease booking was not properly recognized in lease log controller.
The lease booking id (1) on the same error page is correct:
Parameters:
{"lease_booking_id"=>"1"}
Is there a way to fix it? Thanks.
UPDATE: Here is the output of rake routes
lease_booking_lease_logs GET /lease_bookings/:lease_booking_id/lease_logs(.:format) {:action=>"index", :controller=>"lease_logs"}
POST /lease_bookings/:lease_booking_id/lease_logs(.:format) {:action=>"create", :controller=>"lease_logs"}
new_lease_booking_lease_log GET /lease_bookings/:lease_booking_id/lease_logs/new(.:format) {:action=>"new", :controller=>"lease_logs"}
edit_lease_booking_lease_log GET /lease_bookings/:lease_booking_id/lease_logs/:id/edit(.:format) {:action=>"edit", :controller=>"lease_logs"}
lease_booking_lease_log GET /lease_bookings/:lease_booking_id/lease_logs/:id(.:format) {:action=>"show", :controller=>"lease_logs"}
PUT /lease_bookings/:lease_booking_id/lease_logs/:id(.:format) {:action=>"update", :controller=>"lease_logs"}
DELETE /lease_bookings/:lease_booking_id/lease_logs/:id(.:format) {:action=>"destroy", :controller=>"lease_logs"}

Your parameter output shows shat param you should be looking for - lease_booking_id :
#lease_log = LeaseBooking.find(params[:lease_booking_id]).lease_log.new()
From the console, run rake routes to see how the nested routes use the parameters.
Edit:
When you nest your routes the inner resources depend on the outer resource:
resources :lease_bookings do
resources :lease_logs
end
Look at the rake routes output for creating your lease_log:
POST /lease_bookings/:lease_booking_id/lease_logs
So when you set up your form you need to specify the lease_booking as well as the new lease_log (and any _path or _url methods will need to be adapted accordingly):
<%= simple_form_for [#lease_booking, #lease_log] do |f| %>
This would also require you to set the #lease_booking in your controller:
See http://guides.rubyonrails.org/routing.html for more information on Rails routing.
def new
#lease_booking = LeaseBooking.find(params[:lease_booking_id])
#lease_log = #lease_booking.lease_log.new
end

Here is a perfect example I found to construct both controller and view for 1-to-many association:
http://jonathanhui.com/ruby-rails-3-model-1-many-association

Related

No route matches {:action=>"show", :controller=>"posts"} missing required keys: [:id]

I'm struggling with this line in the _form: <%= simple_form_for(#post, url: blog_path) do |f| %>, which gives me the error:
No route matches {:action=>"show", :controller=>"posts"} missing required keys: [:id]
Keep in mind that in my routes I have: resources :blog, controller: 'posts', which is to say I am working off of a posts MVC, but I wanted /posts/ to be replaced by /blog/ in the routes.
posts_controller
def new
#post = Post.new
end
def edit
end
The _form works when I go to edit, but not create new.
routes
blog_index GET /blog(.:format) posts#index
POST /blog(.:format) posts#create
new_blog GET /blog/new(.:format) posts#new
edit_blog GET /blog/:id/edit(.:format) posts#edit
blog GET /blog/:id(.:format) posts#show
PATCH /blog/:id(.:format) posts#update
PUT /blog/:id(.:format) posts#update
DELETE /blog/:id(.:format) posts#destroy
model_path by default routing logic in Rails leads to blog#show => /blogs/:id
Change it to blogs_path.
Looking at you routes, I see obvious naming conflict, you must be defined routes wrong.
Be sure it looks like resources :posts, :as=>"blogs", both plural.
UPD
If you want to have only one blog, then resource :post, :as=>"blog", both singular.
But that means one actual input. I'm quite sure you speak of blog/post1, blog/post2, otherwise I can't see any sense in calling it blog?
sorry my english...
<%= simple_form_for(#post, url: blog_path) do |f| %> In this line you are redirecting the form to show (blog_path)
But , depending on the route , the show needs an id (blog GET /blog/:id(.:format)).
You must create a "create" method in the controller that receives the parameters strong ...
There is another method you can use: rails generate scaffold_controller posts
This will build the full CRUD , so you only have to configure the parameters
I hope that helps you
I got best of both worlds this way:
resources :blog, to: 'posts'
resources :posts

undefined method in rails

I get the error
undefined method `favorite_relationships_path'
when I display this form:
<%= form_for(current_user.favorite_relationships.build(lesson_id: #lesson.id),
remote: true) do |f| %>
<div><%= f.hidden_field :lesson_id %></div>
<%= f.submit "Favorite", class: "btn btn-large btn-primary" %>
<% end %>
I'm not sure why. I have a controller called favorite_relationships_controller.rb and a model file, favorite_relationship.rb, with the code
class FavoriteRelationship < ActiveRecord::Base
attr_accessible :lesson_id
belongs_to :user
belongs_to :lesson
end
My user model also has:
has_many :favorite_relationships
has_many :lessons, :through => :favorite_relationships
I'm really not sure why im getting that error. Help would be appreciated.
Rails has _path and _url helpers for routes, which are set up in config/routes.rb. You'll need to ensure that you've defined the routes for FavouriteRelationshipController; something like:
resources :favourite_relationships
You can check the routes defined for your application using the rake routes command.
You can find more information about routing at the Rails Routing from the Outside In guide.
Defining controllers, actions and views is not enough. You need to define routes in config/routes.rb to connect URLs to your controllers/actions. Defining RESTful resources with resources :favourite_relationships in your routing file is what causes Rails to generate the *_path and *_url helpers; until you do this there is no way for requests to reach your app, and no way for your app to generate routes based on your models.
Your routes file should look something like this:
MyApp::Application.routes.draw do
resources :favourite_relationships
end
This generates the typical "CRUD" routes required for a RESTful resource:
favourite_relationships GET /favourite_relationships(.:format) {:action=>"index", :controller=>"favourite_relationships"}
POST /favourite_relationships(.:format) {:action=>"create", :controller=>"favourite_relationships"}
new_favourite_relationship GET /favourite_relationships/new(.:format) {:action=>"new", :controller=>"favourite_relationships"}
edit_favourite_relationship GET /favourite_relationships/:id/edit(.:format) {:action=>"edit", :controller=>"favourite_relationships"}
favourite_relationship GET /favourite_relationships/:id(.:format) {:action=>"show", :controller=>"favourite_relationships"}
PUT /favourite_relationships/:id(.:format) {:action=>"update", :controller=>"favourite_relationships"}
DELETE /favourite_relationships/:id(.:format) {:action=>"destroy", :controller=>"favourite_relationships"}

Routing Rails Admin Controller Create Action

A dedicated admin/countries_controller is being correctly used for all actions (index, ...), except for creating records. Here the regular countries_controller from the parent controller directory is active:
Started POST "/countries" for 127.0.0.1 at 2011-06-29 23:26:38 +0200
Processing by CountriesController#create as HTML
What is missing to have the POST action being routed to admin/countries?
routes.rb:
resources :countries
namespace :admin do
resources :countries
end
rake routes:
countries GET /countries(.:format) {:action=>"index", :controller=>"countries"}
POST /countries(.:format) {:action=>"create", :controller=>"countries"}
new_country GET /countries/new(.:format) {:action=>"new", :controller=>"countries"}
admin_countries GET /admin/countries(.:format) {:action=>"index", :controller=>"admin/countries"}
POST /admin/countries(.:format) {:action=>"create", :controller=>"admin/countries"}
new_admin_country GET /admin/countries/new(.:format) {:action=>"new", :controller=>"admin/countries"}
Similar question unanswered here:
Rails help with building Admin area - Routing problem
Your form_for needs to be namespaced too:
<%= form_for [:admin, #country] do |f| %>
...
<% end %>
When you pass #country to form_for it's not going to know what namespace you want this form to go to and so it will default to just the standard POST /countries URL.

Rails 3 restful route problem

The following link works in my app:
<%= link_to "invitation", :controller => :invitations, :action => :index %>
To follow restful conventions i changed the link to:
<%= link_to "invitation", index_invitation_path %>
The error that i get is:
undefined local variable or method `index_invitation_path'
Rake routes yields:
invitations GET /invitations(.:format) {:controller=>"invitations", :action=>"index"}
The page name is index.html.erb. The model is invitation.rb. The controller is invitation_controller.rb. Routes has resources :invitations. What am i missing?
Thanks!
Assuming you have the routing correct:
resources :invitations
Then the correct helper for the index action (with the url /invitations.html) is
invitations_path
You can see more information by running rake routes. It will display text like the following:
lists GET /lists(.:format)
{:action=>"index", :controller=>"lists"}
POST /lists(.:format)
{:action=>"create", :controller=>"lists"}
new_list GET /lists/new(.:format)
{:action=>"new", :controller=>"lists"}
edit_list GET /lists/:id/edit(.:format)
{:action=>"edit", :controller=>"lists"}
list GET /lists/:id(.:format)
{:action=>"show", :controller=>"lists"}
PUT /lists/:id(.:format)
{:action=>"update", :controller=>"lists"}
DELETE /lists/:id(.:format)
{:action=>"destroy", :controller=>"lists"}
root /(.:format)
{:controller=>"lists", :action=>"index"}
The above was from a route of my own (for a model called List). The route helper method is shown immediately before the HTTP method. You have to remember to append the _path to each helper method. For example the helper methods I could use are:
list_path(list)
edit_list_path(list)
new_list_path
lists_path
You'll need a route in your routes.rb file that defines a mapping to the invitations controller and the index action.
Typically this is created with a resources call
resources :invitations
Which creates several default routes, which you can see by running rake routes.
For single resources, you can also define it using a match call
match "invitations/:id" => "invitations#index", :as => index_invitation
The rails site has a great resource on routing that provides all the details: Routing from the Outside In
Update: Based on your updated question, your route includes an invitaions (notice the trailing 's') route - nothing with index or invitation. The index_ prefix is generated by the resources call when it creates the default routes for :invitations.
It looks like you've defined a custom get mapping for an invitation. While this may technically work, if you're aim is to support restful routes, use the resources method. And have a read of the Routing guide from rails it's very easy to follow and quite detailed.
type rake routes in your console and look at listing of available routes. Seems to be there is no such route index_invitation_path? maybe it named differently
I think you need "invitations_controller.rb" to contain InvitationsController. Plural.

ruby on rails no route matches action :delete

I'm setting up friendships within a RoR website. The model for it is user_id, friend_id, and pending (boolean). I followed the RailsCast on friendships for the most part, but making some changes to it too. What I have so far is that when you go to a user's page you can click Request Friendship and the code uses:
user_friendships_path(current_user, :friend_id => #user), :method => :post
This calls the create method in the Friendships controller. It automatically sets pending to true. What I want now is to have a link to Accept it which would just turn pending to false. So I am trying to set it up like
(<%= link_to "Accept", user_friendship_path(:user_id => current_user.id, :friend_id => friendship.user.id, :pending => 'false'), :method => :put %>)
I don't actually want to go to the edit page, because it just needs to set that boolean to false, so I want to call the update directly. But when I run this page, I get the error:
No route matches {:action=>"destroy", :controller=>"friendships", :user_id=>1, :friend_id=>2, :pending=>"false"}
I don't understand why. I'm not calling the destroy (that would be with :method => :delete), and there actually is a destroy method within the Friendship controller.
The resources are set up like:
resources :users do
resources :friendships
end
And the paths from running "rake routes" are:
user_friendships GET /users/:user_id/friendships(.:format) {:action=>"index", :controller=>"friendships"}
user_friendships POST /users/:user_id/friendships(.:format) {:action=>"create", :controller=>"friendships"}
new_user_friendship GET /users/:user_id/friendships/new(.:format) {:action=>"new", :controller=>"friendships"}
edit_user_friendship GET /users/:user_id/friendships/:id/edit(.:format) {:action=>"edit", :controller=>"friendships"}
user_friendship GET /users/:user_id/friendships/:id(.:format) {:action=>"show", :controller=>"friendships"}
user_friendship PUT /users/:user_id/friendships/:id(.:format) {:action=>"update", :controller=>"friendships"}
user_friendship DELETE /users/:user_id/friendships/:id(.:format) {:action=>"destroy", :controller=>"friendships"}
Any help would be greatly appreciated. Please let me know if you require more information.
Thanks.
The path that exists according to rake routes is
user_friendship PUT /users/:user_id/friendships/:id(.:format) {:action=>"update", :controller=>"friendships"}
The method you are using is put, but you aren't supplying ':id'.
There are two solutions depending on what you are trying to do:
Change the method to get - that will point you to the new action
Add :id to your URL builder - that will point you to the update action
Your code is leaning towards the second, but I think if you want to create a new friendship, the first would be better.
I'm baffled as to why the URL helper is mapping to a destroy action. However there is a simpler problem: user_friendship_path expects params :user_id and :id, not :friend_id.

Resources