Route errors when using namespace routes - ruby-on-rails

How do you deal with form_for's when the routes are namespaced? I am getting some weird route errors that I really expect to get.
For example, let's say you have a controller called Admin::CompaniesController in
your :admin namespace in your routes.rb:
namespace :admin do
resources :companies
end
Most things work just fine, but I get an error when I render a new form. Here's the code:
<%= simple_form_for(#company, :url => admin_company_path(#company)) do |f| %>
And here's the error message:
ActionView::Template::Error: No route matches {:action=>"show", :controller=>"admin/companies", :id=>#<Company id: nil, name: nil, phone_number: nil, address: nil, postal_code: nil, is_enabled: true, courses_created: 0, province_id: nil, theme_id: nil, payment_plan_id: nil, created_at: nil, updated_at: nil>}
How can I get rails to play nice here? I obviously want one url for edits, and another for new forms. Usually, I'd never even have to put :url in my form_for statements, but because of the nesting, I am forced to.
I have no idea what to do here now, at least not elegantly.

Try using simple_form_for([:admin, #company]) do |f|

I believe I just have to pluralize the path at the end of the path, like this:
<%= simple_form_for(#company, :url => admin_companies_path(#company)) do |f| %>
This is not what I would have expected. I just guessed at it. This is not a valid route or anything, but it seems to work for puts and posts.

Related

Error in displaying data in Rails

I am trying to display data in the view for a member's profile. When I run the inspect option on the variable, it prints out all of the data on the profile variable. But, when I have it only call a column, I get an error.
I run the same code on a different variable and it prints out; so, I am a bit confused on what is going on. Is it because the Active Record has a relation? Here is the code:
profiles_controller.rb
def show
#show_page = params[:id]
#member = current_member
#profile = Profile.where(member_id: current_member.id)
end
show.html.erb
<hr>
<%= #show_page.inspect %>
<hr>
<%= #profile.inspect %>
<hr>
<%= #member.inspect %>
<hr>
<p>
<strong>Member ID:</strong>
<%= #member.id %>
</p>
View in Browser
"8"
#<ActiveRecord::Relation [#<Profile id: 6, f_name: "Test", l_name: "Member", u_name: "testing", security: "10", private: "1", avatar: nil, birthday: nil, phone: nil, address1: nil, address2: nil, city: nil, state: nil, zip: nil, long: nil, lat: nil, facebook: nil, twitter: nil, instagram: nil, pinterest: nil, googleplus: nil, motto: nil, created_at: "2017-12-23 05:15:53", updated_at: "2017-12-23 05:15:53", member_id: 8>]>
#<Member id: 8, email: "testing#t.com", created_at: "2017-12-19 20:02:34", updated_at: "2017-12-23 05:15:37">
Member ID: 8
Now, when I add the following code into the show page, I get an error.
show.html.erb
<p>
<strong>User Name:</strong>
<%= #profile.u_name %>
</p>
ERROR
Showing /Users/topher/Dropbox/railsapps/~sandboxes/temporary/app/views/profiles/show.html.erb where line #21 raised:
undefined method `u_name' for #<Profile::ActiveRecord_Relation:0x00007fcb2583b920>
Did you mean? name
I am just confused on if there is a different way that I need to be calling the data found in the variable. The only difference between the #member and #profile print outs that I can see is the #<ActiveRecord::Relation [ prefixed to #profile. Does this mean that I need to call the information differently?
#where is query method, and returns records matching query conditions wrapped in ActiveRecord::Relation object. Which explains why you are getting this error. To resolve it, you need to change it to:
#profile = Profile.where(member_id: current_member.id).first
Which will return first record matching given member id to #profile instead of ActiveRecord::Relation object.
However, you must use a finder method in case you want to find a particular record. So better and cleaner approach would be:
#profile = Profile.find_by(member_id: current_member.id)
Change the line in profiles_controller.rb like
#profile = Profile.find_by(member_id: current_member.id)
As you are using where clause on Profile it will return an array of ActiveRecord::Relation objects. But you need a single #profile object not #profiles object. Thats you should use find_by method instead of where clause.
I think the problem is your line on the show method
#show_page = params[:id]
You need to indicate model where to contain the params id
#show_page = Model.find(params[:id]) #=> model is your model which you can using
I think will help

Rails no route matches controller

I am trying to pass both a user id, and a test id to a controller using link_to. Below is my code:
<%= link_to(test.name, user_test_result_path(:userd_id => 1, protocol.id)) %>
and below are my routes:
but I keep getting the following error:
Why is it saying that no route matches :action => show and :controller=>"test_results when according to my routes it does exist?
Dude. It says userd_id here:
<%= link_to(test.name, user_test_result_path(:userd_id => 1, protocol.id)) %>
Spelling matters!
Also, where is that:
{9=>2...}
coming from in your params? I'm guessing you'll have more luck if you do something like:
<%= link_to(test.name, user_test_result_path(id: protocol.id, user_id: 1)) %>
You shouldn't be passing a hash to your path helper. If your path has two segments, :user_id and :id, you would simply invoke helper_name(user_id, id), not helper_name(user_id: user_id, id).
In your case you should be calling
user_test_result_path(1, protocol.id)

Rails Routing Questions

I am very new to Ruby on Rails and I have been working with a project while learning but I have run into an issue. I am trying to set up a link from a view under a "task" controller to a view for new timetracks. I am attempting to link on the view like so:
<%= link_to "New Timetrack", new_project_list_task_timetrack_path(#project, #list, #task) %>
And I am getting this error:
No route matches {:action=>"new", :controller=>"timetracks", :project_id=>nil, :list_id=># < List id: 1, name: "Test", description: "Test", created_at: "2013-12-18 21:00:39", updated_at: "2013-12-18 21:00:50", project_id: 1, default: nil>, :task_id=>#>Task id: 1, description: "First Task", completed: false, list_id: 1, created_at: "2013-12-18 21:00:57", updated_at: "2013-12-18 21:00:57", default: nil>}
I made sure that there was an action "new" in the timetracks controller. I am creating the link the way above because of how I saw Rails scaffold the relation between projects and lists which was like so:
<%= link_to "Create To-Do", new_project_list_path(#project) %>
So I'm stumped and would like some help. Any information is appreciated!
Try to use new_project_timetrack_path
If it helpless, look at the output of bash command rake routes and find route that you need.
in your config/routes.rb must be rows like these:
resources :projects do
resources :lists do
resources :tasks do
resources :timetracks
end
end
end
and then rake compile path like
host:3000/projects/<project_id>/lists/<list_id>/tasks/<task_id>/timetracks/new
I hope this can help you.

Why does rails console give different size of relationship than in the server?

My relationship between posts and comments are showing differently in the rails console and the web server! How could that be? I was confused because a partial was rendering with wrong links, and I thought something else was wrong, but the partial should not have rendered at all because the collection should be empty! I even use an if/else to check the size, and it was still showing the partial for the empty relationship!
Rails Console:
irb(main):033:0> p=Post.find(6)
=> #<Post id: 6, title: "Yahoo", comment: "The home page.", link: nil, user_id: nil, created_at: "2013-10-06 21:53:24", updated_at: "2013-10-07 00:43:25">
irb(main):034:0> p.comments.size
=> 0
posts/show.haml:
%h2 Comments
Post ID:
=#post.id
, Comment Size:
=#post.comments.size
- if #post.comments.empty?
No comments.
- else
= render #post.comments
Browser: http://127.0.0.1:3000/posts/6
Comments
Post ID: 6 , Comment Size: 1
Commenter:
comments/_comment.haml: Doesn't seem relevant...
Rails 4.0.0, ruby 2.0.0p247 (2013-06-27) [i386-mingw32]
Maybe there is a form for new comment somewhere on this page and you build new comment in controller:
#new_comment = #post.comments.build
That's why #post.comments.count is 1. You could rewrite your code:
= #post.comments.reject{ |t| t.new_record? }.count
UPD.
There is a nicer way to do this thing: instead of adding reject method you could add scope in your Comment model:
scope :saved, where('id is not ?', nil)
And then in view:
#post.comments.saved.count

Creating new child in nested routes

This one is driving me crazy. I've got a nested relationship between two models in my project, and I decided I did not want it to be shallow, since the child object (years) has no meaning outside the context of the parent (festivals).
So I sort of de-shallowed the relationship wherever I could find a reference to it, but I find myself unable to access the page to create a new child object.
Here's the url as I understand it should be: /festivals/1/years/new
from routes.rb:
resources :festivals do
resources :years
end
From years_controller.rb:
# GET festivals/1/years/new
# GET festivals/1/years/new.json
def new
#festival = Festival.find(params[:festival_id])
#year = #festival.years.build
respond_to do |format|
format.html # new.html.erb
format.json { render :json => #year }
end
end
And the button users press to get to the New page (on the Show page for the parent object):
<%= link_to 'Add Year', new_festival_year_path(#festival), :class => 'btn' %>
That takes the user to the correct URL, but I get:
No route matches {:action=>"show", :controller=>"years", :festival_id=>#<Festival id: 7, name: "Improganza", founded: nil, logo: "", mission: "This is that one that people spend a lot of money t...", city: "Honolulu", state_code: "HI", country_code: "US", created_at: "2013-07-26 14:49:19", updated_at: "2013-07-26 14:49:19">}
I created a new Rails project and set up scaffolds using Akria Matsuda's nested_scaffold gem, just to compare that output with my code... the resulting files look as I've shown here. I have no idea what I might be missing.
Just for good measure, the output of my rake routes:
festival_years GET /festivals/:festival_id/years(.:format) years#index
POST /festivals/:festival_id/years(.:format) years#create
new_festival_year GET /festivals/:festival_id/years/new(.:format) years#new
edit_festival_year GET /festivals/:festival_id/years/:id/edit(.:format) years#edit
festival_year GET /festivals/:festival_id/years/:id(.:format) years#show
PUT /festivals/:festival_id/years/:id(.:format) years#update
DELETE /festivals/:festival_id/years/:id(.:format) years#destroy
festivals GET /festivals(.:format) festivals#index
POST /festivals(.:format) festivals#create
new_festival GET /festivals/new(.:format) festivals#new
edit_festival GET /festivals/:id/edit(.:format) festivals#edit
festival GET /festivals/:id(.:format) festivals#show
PUT /festivals/:id(.:format) festivals#update
DELETE /festivals/:id(.:format) festivals#destroy
GET /festivals(.:format) festivals#index
POST /festivals(.:format) festivals#create
GET /festivals/new(.:format) festivals#new
GET /festivals/:id/edit(.:format) festivals#edit
GET /festivals/:id(.:format) festivals#show
PUT /festivals/:id(.:format) festivals#update
DELETE /festivals/:id(.:format) festivals#destroy
Try this:
<%= link_to 'Add Year', new_festival_year_path(#festival.id, :class => 'btn' %>
or
<%= link_to 'Add Year', new_festival_year_path({festival_id: #festival.id}, :class => 'btn' %>
according to the error you're getting
:festival_id=>#<Festival id: 7, name: "Improganza", founded: nil, logo: "", mission: "This is that one that people spend a lot of money t...", city: "Honolulu", state_code: "HI", country_code: "US", created_at: "2013-07-26 14:49:19", updated_at: "2013-07-26 14:49:19">}
the router is getting your whole festival param as the input for :festival_id
I think you are merging together the #new and #year actions in the years_controller and that might be causing some problems.
# GET festivals/1/years/new
# GET festivals/1/years/new.json
def new
#festival = Festival.find(params[:festival_id])
#year = #festival.years.build
end
def create
#festival = Festival.find(params[:festival_id])
#year = #festival.years.create(...)
#...fill in the rest of the method...
end
You also should update your link:
<%= link_to 'Add Year', new_festival_year_path(festival_id: #festival), :class => 'btn' %>
I created a short quiz on nested resources that might be helpful.
The answer was fairly silly. In my Rails server log (which I need to train myself to pay more attention to), I saw the some lines indicating a problem in line 63 of my _form.html.erb partial.
That line was:
<%= link_to t('.cancel', :default => t("helpers.links.cancel")),
festival_year_path(#festival), :class => 'btn' %>
Oops. Why I ever decided the "Cancel" button should take you to a year (that, of course, would not exist) is beyond me. I changed it to festival_path(#festival) and it's all good.
Thanks, everyone, for your help. I'm a newcomer to StackOverflow and to Rails in general. It really makes me feel welcome that I got such quick responses!

Resources