I'm trying to show devise error message from another action. I have Registrations Controller with subscription action.
I would like to show error message from my subscription action when the user has already signed up. So this is kind a update of existing user, but without password, just validation for attributes.
If validation fails devise shows error message via subscription action.
By default when the user get updated error message is rendered via update action.
I assume I need to reuse the code from Registrations Controller update action and apply this code to my subscription action, but no luck. Can anyone help to make to show error message from subscription action?
here devise registrations controller
Ideally, you should create a separate controller SubscriptionController which contains new and create (RESTful actions?) which enable you to display a form where you accept the user details and process it, respectively.
Here, in the SubscriptionController's create action, you can append errors to the flash hash provided by the ActionController.
class SubscriptionController < ActionController
def create
flash[:success] = 'User Registered Successfully'
end
end
In your view(layout), you can have something like this:
<% flash.each do |name, msg| %>
<div class="flash">
<%= msg %>
</div>
<% end %>
which will allow you to display the flash message.
Related
Rails 4.2.6
Devise 4.1.1
I want to redirect to a specific page after user has successfully updated his data using devise. Here is the Controller:
protected
def after_update_path_for(resource)
#email = resource.email
after_update_path
end
Here is the view:
<h3><%= #email %></h3>
Nothing shows up, any sugeestion?
you need to pass the data as parameter to another controller. because you are doing redirect not render. but probably you don't need that because since the user still have the session, you can show the data of the current user via current_user method.
so
<h3><%= current_user.email %></h3>
should work for you
Users can accept a project, or an admin user can do it on their behalf. Regardless of the sender, an email is sent. I would like the contents of the email to be different when an admin triggers its' sending.
There's a current_user method in ApplicationController. When current_user.admin? evaluates to true, I'd like to do something else.
How can I access current_user from either inside the mailer's view template or from the *_mailer.rb itself?
I'm also open to working with controller/action names. For example, if controller_name == "Admin". It'll get us there, but this method is unavailable in the mailer as well.
Just pass the current_user to the mailer when you are creating a new delivery:
YourMailer.conditional_creation_email(current_user).deliver_now
In your_mailer.rb
def conditional_creation_email(sender)
if sender.admin?
# do...
mail(to: '#gmail.com', subject: 'New Order')
end
end
class UserSessionsController < ApplicationController
def new
#user_session = UserSession.new
end
def create
#user_session = UserSession.new(params[:user_session])
if #user_session.save
flash[:notice] = "Successfully logged in."
redirect_to root_path
else
render :action => 'new'
end
end
Am new to RoR, So long i have been working on tradition c/c++ so i have some basic doubts about object creation and stuff,
In UserSessionsController there is two methods namely "new" and "create". In the "new" method an object for UserSession is created without any parameters and in "create" method again object is created with some parameter.
Initially i thought that the "new" method is redundant and removed it. But i recieved the following error
Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id
The code works fine if i include the "new" method. I couldn't see this method being called anywhere in the entire code. Am referring to following sample project
railscasts/160-authlogic
Kindly let me know how this object creation is happening.
Thanks.
new and create are part of CRUD.
new action is used to render the new view for the UserSessionsController. In new action you simply create an instance of UserSession model class with #user_session = UserSession.new. After this, new.html.***(* is template handler like erb, haml, etc) is rendered where you will enter details of UserSession object that you would like to be created. Upon submission of this form create action would be invoked.
In create action you collect the parameters passed from the new view with #user_session = UserSession.new(params[:user_session]) and when you say #user_session.save it actually creates a record in database table user_sessions
UPDATE
The new action is invoked when you click on the Login Link. Why is it invoked? Because you have defined the login_path in routes.rb
Since you are a beginner I would highly recommend you to:
Read the Getting Started with Rails which will help you to understand the fundamentals of a Rails Application development.
Then, I also recommend you to complete Learn Rails by Example By
Michael Hartl.
And finally, watch the Ruby on Rails Railscasts By Ryan Bates.
Although, you can search on Google and you will find many great resources for the Rails beginners but the above 3 are THE de facto ones.
The 'new' action is generally used in combination with a user interface that will accept input from the user such as a form. It is not strictly necessary that the new action create a new UserSession object, but it is necessary if you want to use a "form_for" helper.
<% form_for #user_session do |f| %>
As you can see, if #article is not defined, this form will raise an error. The benefits of using form_for are that rails will automatically generated the correct params for you when you submit the form and send the form-data to the create action. For example:
<% form_for #user_session do |f| %>
<%= f.label :user_session %><br />
<%= f.text_field :user_session %>
<p><%= f.submit "Submit" %></p>
<% end %>
This form will create a param user_session[:user_session] when you submit the form. Now, when you call:
#user_session=UserSession.new(params[:user_session])
the #user_session object will have its user_session attribute automatically set to the value passed in by the form. This might seem trivial when there is only one attribute, but in a form with many attributes the ability to instantiated a new object and set all the attributes in one line is nice.
This functionality can be recreated by hand but the form_for helper does all the work for you.
In UserSessionsController the new and create methods refer to controller actions that correspond to particular RESTful HTTP requests (routes). In this case, a GET /user_sessions/new HTTP request would invoke UserSessionsController#new and a POST /user_sessions HTTP request would invoke UserSessionsController#create.
The new action renders the form (found at views/user_sessions/new.html.erb) for creating a new user session. That view expects you to provide a user session object as #user_session, which is accomplished in the controller's new action by the #user_session = UserSession.new statement. Without that line, the view is trying to render the form with a nil object reference, resulting in your error.
The create action handles the form submission that comes from new. It expects to see a hash of properties that are appropriate for a UserSession. UserSession.new is called with that hash of properties, creating a new UserSession populated with data from the submitted form. Calling save on the UserSession instance runs validations, which can potentially fail. You can see that if the save succeeds, the controller will redirect the user to the root URL with a "Success!" flash message. If it fails, it sends the user back to the form to fix their mistakes.
I am trying to figure out the best way to do the following (there are a few ways I can think of, but I want to know what the best way to handle it is):
A user is putting together a shipment, and then clicks the "Send" link, which sends him to the /shipments/:id/confirm page. The confirm action checks to see if the user has a completed ShippingAddress; if not, it sends him to the ShippingAddress#new. (If he does, it render the confirm page.
I want the user to be able to complete the ShippingAddress#new page, submit it, and then be redirect back to the /shipments/:id/confirm. How can I do that? How can I pass the :id to the ShippingAddress#new page without doing something like redirect_to new_shipping_address_path(shipment_id: #shipment.id) in the Shipment#confirm action? Or is that the best way to do that?
class ShipmentsController < ApplicationController
def confirm
#shipment = Shipment.where(id: params[:id]).first
unless current_user.has_a_shipping_address?
# Trying to avoid having a query string, but right now would do the below:
# in reality, there's a bit more logic in my controller, handling the cases
# where i should redirect to the CardProfiles instead, or where I don't pass the
# shipment_id, and instead use the default shipment.
redirect_to new_shipping_address_path(shipment_id: #shipment.id)
end
end
end
class ShippingAddressesController < ApplicationController
def new
#shipment = Shipment.where(id: params[:shipment_id]).first
end
def create
#shipment = Shipment.where(id: params[:shipment_id]).first
redirect_to confirm_shipment_path(#shipment)
end
end
[In reality, there is also a CardProfiles#new page that needs to be filled out after the shipping address is].
Try calling render instead of redirect_to, and set the id into an instance variable. Adjust the view logic to pull that instance variable if it exists.
#shipment_id = #shipment.id
render new_shipping_address_path
In the view
<%= form_for #shipment_address do |f| %>
<% if #shipment_id %>
<%= hidden_field_tag :shipment_id, #shipment_id %>
<% end %>
I don't know your view logic entirely, but giving an example.
I am in chapter 8 of the book, where we are trying to implement the signup functionality for the sample app with actions "new" and "create". Here is my questions about these 2 methods/actions,
The "new" action/method is defined as below in the User controller
class UsersController < ApplicationController
.
.
.
def new
#user = User.new
#title = "Sign up"
end
end
here the #user is defined so that its is accessible in the form of the html page for signup. As soon as the user hits signup button the "create" action/method of the user controller gets called, the code for the create action/method is below,
class UsersController < ApplicationController
.
.
.
def create
#user = User.new(params[:user])
if #user.save
# Handle a successful save.
else
#title = "Sign up"
render 'new'
end
end
end
Here is my question,
why are we calling "User.new" twice once inside the "new'method/action and inside "create" method/action" ?
Thanks for the reply,
what if I implement the create method like the one below, I have removed the second call to new, Is this wrong. if so what is wrong ?
def create
if #user.save
# Handle a successful save.
else
#title = "Sign up"
render 'new'
end
end"
Thanks
If you are using the form_for implementation on the erb view.
This uses the #user object to associate the fields with the objects attributes.
This fields will be passed as key value pairs.
<%= form_for #user do |u| %>
<%= f.text_field :name %><br />
<%= f.text_field :age %><br />
<%= f.submit %>
<% end %>
For this you create a blank user object in the new method.
In the create method you create the object with the params submitted.
This helps you to create a User object directly from the parameters, and validate and save the object.
#user = User.new(params[:user])
After the submission of the form, the request params are passed to with the key as user object attributes.
The first time User.new is called, you are creating a model in memory that is used to generate the fields to populate the new user view. That html page then gets returned to the client, and the server forgets all about it. When the client fills out the form and commits it back to the server the create method gets called on the controller. The first thing the controller does is make a new User model, and populate it with the parameters. Until then, nothing has been persisted which is why the new method gets called twice
The first new in the new action is needed to get an empty object, which later is used in the user form in the view, so that Rails form helpers can determine the form object and have something to get the information Rails needs to automatically set all the default values of the form (like the default url to your UserController). With this information the form and page are rendewred and Rails forgets about it. (If the model has default values for some attributes, those will be set too and would appear in the form)
Now you have the form in your browser, fill in the values and submit it. This submit is handled by the create action and here the second new creates an object and fills it with the values submitted from your form and now available in the params hash. This object will have values and the #user.save call will save them to the database if they pass validation (result true). If there are errors, like missing data in mandatory fields, the save will fail and the form from the 'new' view will be rendered again. This time with the data in the object that was created, so all valid data will be filled in the input fields.