I created the following devise scope:
devise_scope :users do get
get 'spotkey' => 'spotkeys#spot_page'
get 'dashboard' => 'spotkeys#dashboard'
post 'dashboard' => 'spotkeys#dashboard'
get 'signup' => 'users/registrations#new', :as => :new_user_session
post 'signin'=> 'users/sessions#create', :as => :user_session
delete 'signout' => 'users/sessions#destroy'
end
controllers/users.rb
class UsersController < ApplicationController
def index
end
def show
#user = User.find_by(id: params[:id])
end
def dashboard
#keys = Spotkeys.all
#keys = Spotkeys.new
#spotkeys = Spotkeys.all
#spotkeys = Spotkeys.new
end
end
views/spotkeys/dashboard.hrml.erb
<div class="key">
<%= #keys.location %><br/>
<%= #keys.picture_url %><br/>
<%= #keys.floor_number %><br/>
<%= #keys.description %><br/>
<%= #keys.floor %><br/>
<%= #keys.buzzer_code %><br/>
<%= #keys.parking_info %><br/>
<%= #keys.cross_street %><br/>
<%= #keys.public_transit %>
</div>
I'm getting the follow error:
missing :controller key on routes definition, please check your routes
Please let me know if you need to see any other files.
Problems I noticed:
Regarding to this comment and devise how-to wiki, devise_scope needs the resource name in singular (devise_for, in contrary, needs the resource name in plural).
You also have a weird get on the same line with devise_scope- it might cause the problem.
Routing mapper, from where the error is raised, also suggests that it does not find such controller. It probably tries to search a controller based on your plural form of devise_scope. OR it tries to find controller name after your extra-get keyword after :users do.
Related
What's the best (simplest) way to walk through MVC and check if everything is set up right?
I get a bit frazzled and I feel like there must be a really simple fix to error messages like these:
undefined method `invitations_path' for #<#<Class:0x00000105ad5cb8>:0x00000105820b30>
After adding small amounts of code to my app things break and I want to trouble shoot them myself.
Thanks for the tips!
EDIT
Perhaps troubleshooting the specific issue will lead way to a generalized approach,
Link_to is not linking Used <%= %> instead of <% %>.
The above error is generated when visting localhost:3000/invitation/new
view (in home/index.erb.html)
<% if #user.invitation_limit > 0 %>
<% link_to 'Send Invitations', new_invitation_path %>
(<%= #user.invitation_limit %> left)
<% end %>
view (in invitation/new.erb.html)
<%= error_messages_for :invitation %>
<% form_for #invitation do |f| %>
<p>
<%= f.label :recipient_email, "Friend's email address" %><br />
<%= f.text_field :recipient_email %>
</p>
<p><%= f.submit "Invite!" %></p>
<% end %>
controller
class InvitationController < ApplicationController
def new
#invitation = Invitation.new
end
def create
#invitation = Invitation.new(params[:invitation])
#invitation.sender = current_user
if #invitation.save
if logged_in?
Mailer.deliver_invitation(#invitation, signup_url(#invitation.token))
flash[:notice] = "Thank you, invitation sent."
redirect_to projects_url
else
flash[:notice] = "Thank you, we will notify when we are ready."
redirect_to root_url
end
else
render :action => 'new'
end
end
end
model
class Invitation < ActiveRecord::Base
belongs_to :sender, :class_name => 'User'
has_one :recipient, :class_name => 'User'
attr_accessible :recipient_email, :sender_id, :sent_at, :token
end
routes.rb
resources :home, :only => :index
resources :invitation
You can create request specs for each of your controller actions. Request specs follow the request all the way from the controller to rendering the view, and if there is an error it will show up in the request spec.
This may take time to set up, but will save you lots of time in the future, as you don't have to manually test every page when you want to roll out a new version of your website.
I'm having a devil of a time getting this particular nested route to work. It's odd, because I've been migrating a number of routes to the new Rails 3 syntax and this one in particular just doesn't seem to work. Here goes.
I've got an object called "piece" which has a nested object called "piece_comment". Here's what the routes.rb looks like:
resources :piece do
resources :piece_rating, :as => :rating
resources :piece_comments, :as => :comments
end
And here is what piece/show.html.erb looks like, with a form to submit a piece comment:
<% #piece_comment = PieceComment.new(:piece_id => #piece.id, :user_id => current_user.id) %>
<%= form_for [#piece, #piece_comment] do |f| %>
<%= f.hidden_field 'piece_comment', 'user_id' %>
<%= f.hidden_field 'piece_comment', 'piece_id' %>
<%= f.text_area 'piece_comment', 'comment' %>
<%= f.submit_tag 'Post' %>
<% end %>
Now, what's weird is that I get the following error triggered by the "form_for" line:
undefined method `piece_piece_comments_path' for #<#<Class:0x007f80ec732a48>:0x007f80ec737ae8>
Shouldn't the :as in my routes file be sending it to piece_comments_path, and not piece_piece_comments_path? if I change it to :as => :foobar or something, I get the same error. So clearly the routes file would not seem to be working correctly. (Oddly, the behavior of the rating route seems fine.)
Any ideas for what might be wrong with the routing?
Altough I'm not sure it is the problem, resources should be plural in the routes.rb. Try with:
resources :pieces do
resources :piece_ratings, :as => :ratings
resources :piece_comments, :as => :comments
end
Use rake routes to see the name of the routes generated by the routes.rb.
Following up on a previous question, I have a few issues to resolve before I have a comment form showing and submitting securely on my profile. I'm a beginner to programming so thinking across multiple controllers seems to have me lost.
What I'm doing is posting comments in a form, then listing them.
Background: The _comment_form and _comment reside as partials in the Profile about. (My next task is toggling from about to other Profile information, but that's another question altogether.)
Using the help provided in my last question I feel like I'm almost there but am getting an error.
CreateComments migration:
t.integer :profile_id
t.integer :author_id
t.string :body
My Comment model:
class Comment < ActiveRecord::Base
belongs_to :profile
belongs_to :author, :class_name =>"User", :foreign_key => "author_id"
end
CommentsController:
def create
#comment = Comment.new(params[:comment].merge(:author_id => current_user.id))
#comment.save!
redirect_to profile_path(#comment.profile)
end
ProfilesController:
def create
#profile = Profile.new(params[:profile])
if #profile.save
redirect_to profile_path(#profile), :notice => 'User successfully added.'
else
render :action => 'new'
end
end
def show
#user = User.find(params[:id])
#profile = #user.profile
#comment = #profile.comments.new
end
Comment partials inside Profile partial:
<div id="commentEntry">
<%= render :partial => 'comment', :collection => #profile.comments %>
</div>
<div id="newitem">
<%= render :partial => 'comment_form' %>
</div>
Routes.rb:
resources :users do
resources :profiles
end
resources :comments
_comment_form.html.erb:
<%= form_for #comment do |f| %>
<%= f.text_field :body %>
<%= f.submit 'Add new' %>
<% end %>
_comment.html.erb:
<li class="comment" title="<%= #comment.author.profile.first_name %> <%= #comment.author.profile.last_name %>">
<%= #comment.body %>
</li>
So, Issue #1: Wrapping the _comment.html.erb in a loop <% for #comment in #user.profile.comments %> shows the profile but when I try and submit a new comment I get "Unknown action The action 'update' could not be found for CommentsController". If I take away the loop, the profile doesn't show and I get "NoMethodError in Profiles#show undefined method `profile' for nil:NilClass". Can anyone help me out and explain what I'm doing wrong?
Issue #2: I created a sample comment in rails console and when I get the profile to show, the input field for comment :body repopulates with the comment's body. Any ideas on what could be going on?
Short explanation of your problem:
The #comment you're getting in your _comment_form partial is one that's already saved in your database, hence the call to the update action and the body that's already filled.
You're creating the new comment just fine with #comment = #profile.comments.new in your show action, but it gets overridden somewhere else.
You're mentioning that you wrapped the _comment render in a loop with <% for #comment in #user.profile.comments %>, the problem is most likely there.
Fix:
The only thing you should have to change is the _comment partial to (without the for loop that you added):
<li class="comment" title="<%= comment.author.profile.first_name %> <%= comment.author.profile.last_name %>">
<%= comment.body %>
</li>
When you do the render :partial => 'comment', :collection => #profile.comments, rails is smart enough to loop over #profile.comments and give the comment (not #comment) variable to the partial.
How to avoid this the next time:
I'll give you two rules of thumb to avoid getting in this situation:
Try to name your variables more precisely. #new_comment would have been a better name for the variable to store the new comment. #comment is a bit ambigous as you've got a boatload of those in your view.
Avoid creating and modifying instance variables (# variables) in your views, try to do this only in your controller. I'll admit your particular case was a bit harder to detect because of the <% for #comment in #user.profile.comments %>. The view got its name for a good reason, it's only supposed to let you view the data you've defined in your controller.
Hope this helps.
I have the following singular route:
scope '/seller' do
resource :seller_profile, :path => "/profile", :only => [:show, :edit, :update]
end
and the following controller:
class SellerProfilesController < ApplicationController
before_filter :validate_user_as_seller
def show
#seller_profile = current_user.seller_profile
end
def edit
#seller_profile = current_user.seller_profile
end
def update
#seller_profile = current_user.seller_profile
if #seller_profile.update_attributes(params[:seller_profile])
redirect_to(seller_profile_path, :notice => 'Profile was successfully updated.')
else
render :action => "edit"
end
end
end
I use a singular route given that the user must be authenticated before gaining access to the controller and therefore I can get the seller_profile from the user logged in.
This works like a charm, with only one problem. When I edit the seller_profile and validation error happen, the form is edited again and the errors are displayed correctly. The problem is that rails appends to the url the id of the edited record. For instance,
when I first edit the record, the url is:
http://0.0.0.0:3000/seller/profile/edit
but if the form is submitted with validation errors, the form itself is redisplayed under
http://0.0.0.0:3000/seller/profile.2
where 2 is the ID of the record being edited.
The form is the following:
<%= simple_form_for #seller_profile do |f| %>
<%= f.input :name %>
<%= f.input :description %>
<%= f.submit %>
<% end %>
Everything, as said, works great but I would totally mask the ID in the url. What should I do?
I have not really worked too much with simple_form_for. But it looks like it is guessing your url always as if they were not single resources. You can provide a custom one:
<%= simple_form_for #seller_profile, :url => seller_profile_path do |f| %>
<%= f.input :name %>
<%= f.input :description %>
<%= f.submit %>
<% end %>
does anyone know how to use a form partial to create and update data about an object? My update method seems to work, but I can't create a new object. Every time I clink on the 'Add new ad' I get this error:[ActionController:Routing Error in Classified#new No route matches {:controller=>classified}]. Here is the code for the partial form: The error points to the first line:
<%= form_for(#classified) do |f| %>
<p>
<%= f.label :title %><br/>
<%= f.text_field :title %>
</p>
<p>
<%= f.label :price %><br/>
<%= f.text_field :price %>
</p>
<p>
<%= f.label :location %><br/>
<%= f.text_field :location %>
</p>
<%= f.label :description %><br/>
<%= f.text_area :description %>
<%= f.label :email %><br/>
<%= f.text_field :email %>
<%= f.submit %>
<% end %>
<%= link_to 'Back', {:action => 'list'} %>
Here are my methods for new, edit and update in the Classified controller class:
def new
#classified=Classified.new
end
Here is the 'def create' method:
def create
#classified = Classified.new(params[:classified])
if #classified.save
redirect_to :action => 'list'
else
render :action => 'new'
end
end
I suspect the problem is in my config/routes.rb. I already have this line:
resources :classified
I have also put:
root :to => "Classified#list"
root :to => "Classified#new"
root :to => "Classified#show"
root :to => "Classified#edit"
root :to => "Classified#form
Could the problem be with the routes.rb file. And how comes it works with the update method and not the new method? Please help. I have tried all possible tricks to no avail. I will be so glad. Thanks in advance
I would like to know the result of your rake routes, because you use the singular for your controller classified.
Could it be classifieds, with the S in all your routes? I'm not that sure because resources: classified I guess came from the scaffold and so it should be good, then you miss a `"' on your last line but this could be a typo.
I would recommend having a plural name for the resource, as that is the norm for most resources:
resources :classifieds
You will also need to change your controller name and class name to classifieds_controller and ClassifiedsController
Also, your named routes should be lowercase (although you should get rid of these routes altogether):
root :to => "classifieds#list"
Get rid of the root routes. The resources line will create all the routes you need. And you are only supposed to have one root route in routes.rb and that should point to your home page controller#action.
If you have an action for form, then you don't need that either.. just mentioning this because you created a route for "Classified#form". Controller actions are not necessary for partials.
Your new and create methods and the form look ok at first glance. Try reworking your routes first and if you are still having problems, run rake routes from the command line and post the output in your question and leave me a comment on this answer and I will see if I can help you figure it out.
Read this first:
http://guides.rubyonrails.org/routing.html