Using if .present? redirect - ruby-on-rails

I feel like this is simple but I'm banging my head against the wall. I'm trying to tell my Rails app that if one parameter is present (signature in this example) that I want to redirect home. Here's my code:
<%= if #pc.signature.present? %><% redirect_to "pages#home" %><%end%>
I keep running into a syntax error. This is in the edit.html.erb file by the way.

Perhaps in your controller you didn't define #pc? also, use path instead of 'pages#home'. it should look more like this:
def edit
#pc = Pc.find(params[:id]) #or whatever your logic is
redirect_to root_path if #pc.signature.present?
# otherwise 'edit' template will be rendered
end

You need to do that on your action controller, not in the view
def your_action
if #pc.signature.present?
redirect_to 'your_path_or_url'
end
end

Related

How to pass objects from one controller to another controller

On an unsuccessful save, I would like to redirect to the previous view but with the error message.
redirect_to user_path(#user_id), errors: #user.errors
but in the view, when I check for errors I get an undefined variable errors.
I am not using the same controller new and create, so I can't have #user.errors.any in new.html.erb. I have two different controllers, one in which form is there, and another controller which will take care of create, if the create is not happening I need to redirect to the previous controller.
You may need to use render instead of redirect_to.
Something like this:
# controller_1
def step_1
#user = User.new
#user.do_something
...
end
# controller_2
def step_2
if #user.save?
# redirect to another...
else
render 'controller_1/step_1`
end
end
Then on view step_1.html.erb, you can print out errors of #user with #user.errors.
You have to pass the parameters inside the redirect_to helper like below,
redirect_to user_path(id: #user_id, error: #user.errors.messages)
Please check the rake routes and pass the appropriate key for id, whether it's :id, or :user_id

undefined method `evm_url'

I have an edit and update methods as follows:
cmdbs_controller.rb
def edit
#evm = Evm.find(params[:id])
end
def update
#evm = Evm.find(params[:id])
if #evm.update(evm_params)
redirect_to #evm
else
render 'edit'
end
end
and routes as follows:
resources :cmdbs do
get :autocomplete_client_name, :on => :collection
collection do
get 'test'
end
end
The problem is that i get an error when submit my edit:
undefined method `evm_url' for #<CmdbsController:0x007fb33ac47d00>
and points me to the redirect_to #evm line.
BTW i am using patch and my url looks like that:
http://localhost:3000/cmdbs/1
The line redirect_to #evm translates to redirect_to evm_path(#evm.id). It uses evm_path because the class of #evm is Evm. So with that, it is expecting to have something like resources :evms in the routes. This means that you have to have another controller called EvmsController. Doing a redirect_to #evm basically redirects to the show action of EvmsController. I'm not sure if that is what you want to happen but that is what Rails is trying to do. Without any other stuff in your routes file, Rails don't know where to redirect.

Rails: Detect if current page ends in "/foo"

How would you detect if the current page ends in ".foo" in Rails?
Basically, I'd like to show different things in my view based on what's passed in the url.
Something like <% if !current_page?('something/something/foo') %> but more dynamic
In Rails 3.2+:
# in your controller
url = request.original_url
#ext = File.extname(url) #=> .foo
# in your view
<% if #ext == '.foo' %>
# do this
<% else %>
# do that
<% end %>
In Rails 3:
# to retrieve the fully qualified URL
url = "#{request.protocol}#{request.host_with_port}#{request.fullpath}"
I'm assuming you're talking about responding with different things depending on the file type requested. Typically, this is what respond_to is for:
class SomeController < ApplicationController
def some_action
respond_to do |format|
format.html { render :new }
format.foo { render :foo }
end
end
end
Otherwise if you really want to just do stuff inside the view, do what zeantsoi showed. This is just kind of irregular. If I knew more about the use case I'd be better able to answer your question.
you can find here how to get full url switch rails version you are using, then after get this url you just need to split it with / then get the last element with .last like this :
url.split("/").last
i think this is the easy way

flash notice is lost on redirect, how to find out what's removing it?

There are many posts on SO about this ( respond_with redirect with notice flash message not working Why is :notice not showing after redirect in Rails 3, among others) , I've read at least 4 and still can't solve this issue.
I've got a portion of my site that lets people do some things before they create an account. I prefer this from a UX perspective. So they're allowed to do X and Y then they get redirected to the "Create account" page (uses Devise).
The redirect looks like:
if userIsNew
... stow information in a cookie to be retrieved later ...
redirect_to "/flash", flash[:notice]
=> "Ok, we'll get right on that after you sign up (we need your email)."
and return # this has to be here, since I'm terminating the action early
end
So "/flash" is a plain page that I made to test this. It doesn't do anything, has no markup of its own, just has the basic html from the application.html, which has this line in the body:
<% if flash[:notice] %>
<p><%= notice %></p>
<% else %>
No notice!
<% end %>
It says 'No notice' every time.
I have tried:
adding in a flash.keep to my before_filter in the static controller
using :notice => instead of flash[:notice] =>
putting the notice in a cookie and pulling that text out of the cookie and into a flash in the before_filter of my application controller
redirect_to :back with the flash[:notice] =>
It's either
flash[:notice] = 'blablabla'
redirect_to foo_url
or
redirect_to foo_url, notice: 'blablabla'
I'm overriding ApplicationController#redirect_to to call flash.keep so that any messages are persisted on redirect without having to explicitly call flash.keep in my controller actions. Works well so far. Haven't had a scenario yet where unwanted messages are persisted.
class ApplicationController < ActionController::Base
def redirect_to(*args)
flash.keep
super
end
end
Let me know if there are any scenarios where this isn't a good solution.
I have been fighting with the same problem for some time and none of the posts seemed to help.
It turns out that - like usually it happens - the the problem was in my code. I did have a "redirect_to" that I forgot about, which was clearing the flash.
Namely, "root_path" for me was served by the StaticPagesController's home method. "home" was doing some checks and then redirecting you to the user_path.
In my code I had in numerous places
redirect_to root_path, :flash => {error: #error}
These redirects were never displaying the flash because my hidden "home" controller serving the "root_path" was making another redirect that cleared the flash.
Therefore my problem was solved when i added the "flash.keep" in my "home" controller method
def home
if current_user
#user = current_user
flash.keep
redirect_to #user unless #user.no_role?
end
end
Faced the same problem, flash just disappeared after any redirect, nothing helped, then, I found that it was switched off...
Check your /config/application.rb for this:
config.middleware.delete ActionDispatch::Flash

Rails way to render different actions & views based on user type?

I have a couple different user types (buyers, sellers, admins).
I'd like them all to have the same account_path URL, but to use a different action and view.
I'm trying something like this...
class AccountsController < ApplicationController
before_filter :render_by_user, :only => [:show]
def show
# see *_show below
end
def admin_show
...
end
def buyer_show
...
end
def client_show
...
end
end
This is how I defined render_by_user in ApplicationController...
def render_by_user
action = "#{current_user.class.to_s.downcase}_#{action_name}"
if self.respond_to?(action)
instance_variable_set("##{current_user.class.to_s.downcase}", current_user) # e.g. set #model to current_user
self.send(action)
else
flash[:error] ||= "You're not authorized to do that."
redirect_to root_path
end
end
It calls the correct *_show method in the controller. But still tries to render "show.html.erb" and doesn't look for the correct template I have in there named "admin_show.html.erb" "buyer_show.html.erb" etc.
I know I can just manually call render "admin_show" in each action but I thought there might be a cleaner way to do this all in the before filter.
Or has anyone else seen a plugin or more elegant way to break up actions & views by user type? Thanks!
Btw, I'm using Rails 3 (in case it makes a difference).
Depending on how different the view templates are, it might be beneficial to move some of this logic into the show template instead and do the switching there:
<% if current_user.is_a? Admin %>
<h1> Show Admin Stuff! </h1>
<% end %>
But to answer your question, you need to specify which template to render. This should work if you set up your controller's #action_name. You could do this in your render_by_user method instead of using a local action variable:
def render_by_user
self.action_name = "#{current_user.class.to_s.downcase}_#{self.action_name}"
if self.respond_to?(self.action_name)
instance_variable_set("##{current_user.class.to_s.downcase}", current_user) # e.g. set #model to current_user
self.send(self.action_name)
else
flash[:error] ||= "You're not authorized to do that."
redirect_to root_path
end
end

Resources