I want to activate a user who signs up by calling the update action in my ActivationController.
In my activation.html.erb file I have this:
<html>
<body>
To activate your account, please click the link below:
<%= link_to "Click Here", activation_url(#user.activation_token), method: :put %>
</body>
</html>
rake routes looks like this:
activation PUT /activations/:id(.:format) activations#update
But when I click this link in the email I get this error:
No route matches [GET] "/activations/icrvr5uNahnA5fpVjVTDEw"
help,
mike
UPDATE
Per the answer below I changed my route to this:
activations_validate GET /activations/validate(.:format) activations#validate
But now how am I supposed to grab the params[:id] from the URL when there is no :id in the route?
In your routes file, try making it a GET instead of PUT, and change the method to something like activations#validate (change in your controller too, obviously), then in the validate method in the controller, check params[:id] against your validation logic, and if successful, update (activate) the user and reroute to where ever.
Related
I have an app where I'm creating a get action called "new_911". When I put new_911_call_path in the application layout I get an error "no route matches new_911 controller: calls". Yet there is an action in the calls controller called new_911. What am I doing wrong?
Calls Controller:
def new_911
#call = Call.new :call_status => "open"
respond_with #call
end
application.html.erb
<li><%= link_to 'New 911 Call', new_911_call_path %></li>
routes.rb
resources :calls do
member do
post 'close'
post 'cancel'
post 'note'
get 'new_return'
get 'duplicate_call'
get 'edit_times'
put 'update_billing'
get 'new_911'
end
rake routes:
new_911_call GET /calls/:id/new_911(.:format) calls#new_911
You need to add the parameter to the route. You're using a member route so you need to add the id parameter, take a look of this. You may need to change that route.
Figured it out. I was using a member instead of a collection. Also using new_911 gave me a constant error so I changed it to EmergencyCalls for my controller schema and utilized the normal "new" action. Added resources :emergency_calls to my routes file and it worked.
Sorry for the goof.
I have made a resource.
resources :dashboards
I have a partial file which contains a form and I want to use this partial (as the form elements won't change) to update and create. So here is what I have:
Controller
class DashboardsController < ApplicationController
def new
#dashboard = Dashboard.new
end
end
View
/dashboards/new.html.erb
<%= render :partial => "form", :locals => { :dashboard => #dashboard } %>
Partial Form
/dashboards/_form.html.erb
<%= form_for(#dashboard) do |form| %>
.....
<% end %>
Ruby Guide
The Ruby Guide states:
The Article model is directly available to users of the application, so — following the best practices for developing with Rails — you should declare it a resource. When dealing with RESTful resources, calls to form_for can get significantly easier if you rely on record identification. In short, you can just pass the model instance and have Rails figure out model name and the rest. For example:
## Creating a new article
# long-style:
form_for(#article, :url => articles_path)
# same thing, short-style (record identification gets used):
form_for(#article)
## Editing an existing article
# long-style:
form_for(#article, :url => article_path(#article), :html => { :method => "put" })
# short-style:
form_for(#article)
Result
I thought I have followed the Rails Guide correctly. Because I made #dashboard a resource. I could just pass it into the form and have it handle the action, method and the rest. Instead I'm getting this:
<form accept-charset="UTF-8" action="/dashboards" class="new_dashboard" id="new_dashboard_" method="post">
According to the docs. Shouldn't the action of my form now be "/dashboards/new" because we are on the new action? And should it be passing an extra field declaring the method to be put when I use the same code in the /edit action??
My result is always the same no matter what. The form never changes.
What am I doing wrong?
EDIT
Here is my router info from rake routes
GET /dashboards(.:format) dashboards#index
POST /dashboards(.:format) dashboards#create
GET /dashboards/new(.:format) dashboards#new
GET /dashboards/:id/edit(.:format) dashboards#edit
GET /dashboards/:id(.:format) dashboards#show
PUT /dashboards/:id(.:format) dashboards#update
DELETE /dashboards/:id(.:format) dashboards#destroy
You are correct that you should be able to "pass #dashboard into the form and have it handle the action, method and the rest." The issue here is what new is in the context of RESTful actions.
When you declare a set of resources with resources :dashboards, you are creating a set of routes which map requests to controller actions:
GET /dashboards index
GET /dashboards/new new
POST /dashboards create
GET /dashboards/:id show
GET /dashboards/:id/edit edit
PUT /dashboards/:id update
DELETE /dashboards/:id destroy
You can check this if you run rake routes.
The issue here is that the new action is defined as a GET request to the path /dashboards/new, i.e. this is the route for the form itself. The URL in the action attribute of the actual form is something else: this is where the form will post the data to with a POST request, which on the server (rails) side will map to the create controller action.
When you use the form helper with form_for(dashboard), a form is created with a route corresponding to what dashboard is: if it is a new record (i.e. it does not yet exist in the database), then the form action will be create (and point to /dashboards), whereas if it already exists it will point to the actual URL for the record (e.g. /dashboards/123). This is what makes the form helpers so useful.
So, to sum up, /dashboards is the correct URL, not for the new action but for the create action, which the form helper uses because dashboard is a new record. new is the route to the page where the form resides, i.e. /dashboards/new.
Hope that makes sense.
p.s. as a side note, you shouldn't be accessing #dashboard in the partial if you are passing it in as a local (:locals => { :dashboard => #dashboard }). Just use dashboard.
My main difficulty comes from understanding the relationship that the _follow and _unfollow partials have with the create and destroy methods defined in the RelationshipsController from Chapter 11.2.3. I'll just focus on the act of unfollowing a user for now (since the act of following is mostly analogous).
Hartl defines the partial for unfollow as such:
<%= form_for(current_user.relationships.find_by_followed_id(#user), html: { method: :delete }) do |f| %>
<%= f.submit "Unfollow", class: "btn btn-large" %>
<% end %>
and the corresponding destroy action as such:
def destroy
#user = Relationship.find(params[:id]).followed
current_user.unfollow!(#user)
redirect_to #user
end
What I am having trouble understanding is:
The #user variable in the first line of the unfollow partial .. is this a) defined in the show action that currently displays the page, or b) defined in the destroy action? It appears that the form_for helper already finds the #user to be destroyed, so why does the destroy action needs to find the #user all over again to be destroyed in the controller?
In the destroy method, the #user is found by first finding the Relationship id. I don't see how the Relationship id is passed into the URI in the first place (since seeing a particular user to unfollow shows up as /users/2), much less how it is used to find the #user to destroy. I understand that each Relationship table has an id, a followed_id, and a follower_id, but do not see how the id element itself comes into play here.
Thanks, for reading, and for answering my questions!!
1.) If the partial is rendered within the show action, the variable #user must be defined in that action. Rails won't execute the destroy method so the variable definition in there will never be executed.
Since HTTP is a stateless protocol, the server needs to create the necessary state on every request. That's why #user must be defined in every action.
2.) Where did you check that the url is "/users/2"? As I don't see the whole code I can only make guesses but the following line current_user.relationships.find_by_followed_id(#user) should return a Relationship object. It will be translated into something like "/relationships/8", where 8 is the ID of the Relationship. Because you specify `method: :delete, the destroy action will be invoked.
I think the url "/users/2" is after the destroy action performed the deletion was performed. There could be a redirect in the destroy action. (eg. redirect_to current_user). You can see all the invoked actions in the log file. Try scrolling through the log and see if you can find RelationshipsController#destroy. You will see the invoked url there. Also you could inspect the HTML to see where the <form> tag's "action" attribute points to.
I'm giving up my search, I normally try to figure these things out on my own but I'm struggling hard and I just want this to work
I have the link_to seen below where #puser is the user of the profile I'm currently viewing.
<%= link_to 'Request', new_or_edit_relationship_path(nil), :remote => true, :locals => { :puser => #puser} %>
This in turn calls new_relationship_path which is a .js.erb file seen below
alert("<%= escape_javascript(puser.id) %>")
Why won't this work!? It's saying the puser variable or method is undefined. This works perfect if I was to just render a partial passing in the locals but no. Javascript doesn't want to play nice
Could anyone help explain why me or the program is stupid?
When you do a link_to as remote, the user is starting an entirely new request when they click the link. So passing a local means nothing to the new request. (The local doesn't exist any more on the new request.)
So in order for the #puser to exist on the new request, you need to pass the id for that #puser via the URL (whatever you have going on for new_or_edit_relationship_path). The new request needs to look up the puser by that id, and then it can use it in the JS alert().
Hope that helps and is a little clearer than mud.
I have a form with <%= text_field_tag "mykey" %>. The user enters myvalue and submits. How to get this value when the POST request hits the Rails server?
I can see myvalue passing in the POST request:
Started POST "/assessments" for 127.0.0.1 at 2011-07-08 20:04:41 +0900
Processing by AssessmentsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"...", "mykey"=>"myvalue"}
But how can I read this value in my controller?
In AssessmentsController#create, first thing I do is log the params, and it is unfortunately empty:
logger.debug session[:assessment_params].collect {|k,v| "#{k}: #{v}"}.join
Note: I can not use text_field instead of text_field_tag, because of another issue.
If your form isn't a model form, which appears to be the case, you just want params[:mykey].