Rails redirect without changing URL - ruby-on-rails

I've some piece of ruby/rails code.
In one of the controllers say foo i have an action doo which does something and I want to redirect to another controller say bar and action say dar.
When I use redirect_to then URL in the address bar changes to /bar/dar while if I use render then I don't know how to render another controller's view.
I am using rails 2.3.5 so render_component is unavailable for use (which i found could be really really useful for me) -- so as a shortcut if you have any idea of alternate for render_component that will help me infinitely.
Any ideas?
[If am unclear please ask me details]

Instead of a real redirect, could you use an AJAX call to hit the action and pull in the appropriate views?

You can render the same partial from both views. You'll have a view for each action and in each of the views you'll have something like <%= render :partial => "partials/form" %>.

You can just call the action (like calling a function) and then render the template. But accordingly to the MVC pattern you should manage your controller-side logic on the controller and then loads the propper view.

Related

Ruby on Rails routes to controllers

As I understand it, routes will take you from a starting point to a controller, and an action. The action brings up the associated views; so what if I don't need any views for my controller, and just want to just call a controller's underlying method, without rendering the view or route.
Lets say I have a FoodsController with several methods, and there exists methods cake, pizza, and chips within that controller. Each one queries the database for a secret message and stores it in a variable, but the request for this is going to come from some other part of our application.
To accomplish this am I supposed to use a route for this or some kind of dot syntax such as food.cake().
So I guess what I am trying to say is, hey "Server" go do this and come back to where you left off once its done.
Controller are only for URL endpoints. For example if you hit http://my.app/my_route, you need to map the my_route part to a controller action in your routes.rb file. But what happens if you type this into your browser? You'll want to see something right? So you need to return some data (json, html, erc). You can use render for this.
This is different to writing 'normal' Ruby code, i.e. Ruby outside a web framework. Do you understand what a class is and how the following works?
class MyClass
def initialize
end
def my_method
puts "my_method_called"
end
end
MyClass.new.my_method # => "my_method_called"
This is very basic Ruby and works in Rails as well, although there are some rules about where code needs to be written.
By the way, if you really want to make a controller action that renders nothing, just use:
render text: "", status: 204
return false
The status: 204 means "No Content".
You can use render json or text, if the method does not render anything, I think it should be private.
In your example you could use the cake method in another controller like so:
cake = Food.cake
Please note that this method should live in the food model and not the controller, since you do not need a view.

Where is the code of rails doing rendering and layouts?

I am working on a project which involves understanding the mechanism of how rails does rendering and layouts, including, where does rails know that it needs to do rendering (either by a render statement or default rendering), which view file it is going to render, how is view file nested together, how does rails merge the layouts with the view file, how does rails decide which layout file to use for a specific render statement. I hope there are some existing code module I can use to produce such rendering results, so I don't have to write code to mimic this process myself.
Backing what the Tin Man said, I'm gonna do my best to answer this as 'How does rendering views work'
First you create a controller....
rails g controller welcome index
This creates the welcome controller with the action index
By action, I mean if you look inside the new welcome controller you will see
def index
end
That's where all the variables and stuff go that you need inside of that 'page' for example if you need to print out all the users, you would do this
def index
#users = User.all
end
Now, inside of /config/routes.rb, when you typed in rails g controller welcome index it generated a route something like this
get '/welcome/index' => 'welcome#index'
What that does, is when someone goes to the URL http://localhost:3000/welcome/index Rails will point to the welcome controller and render the index action
What that will do is tell rails, 'HEY, theres an action called index, go look in /views/welcome and make sure there's a file called index.html.erb
That WILL be there because when you generated the controller, it generates the views for the actions you specify, in this case we only specified index.
Now Rails knows what controller to look in and what action and html to render.
That's pretty much the basics :)
Hope this helps!

Rails Controller action render last page?

I want to redirect to page from where I come is that possible?
What I do:
Calling a controller function from an view, and when action is finished I want to render the same page like a back function?
Thanks
Use
redirect_to :back
You can also pass more params to it. Read more here: http://api.rubyonrails.org/classes/ActionController/Redirecting.html
If what you want is actually render (not redirect) to the last rendered view you can do it in the following way:
render request.referer.split('/').last
It guesses the last rendered view from the request HTTP referer (the URL from which the controller action has been called). Note this approach it's quite fragile, but can be handy in most cases.

What's the best way to do UJS in rails when you have a re-usable widget?

In my current project I have a couple instances where I have a re-usable form that exists inside a rails partial. This form submits to a specific controller via ajax (:remote => true). The controller does some stuff and then returns back the appropriate js.erb to modify the page via javascript.
This works fine for when I have a single view. But the problem seems to happen when this re-usable partial exists on multiple views. In view 1 I might want to issue a completely different set of javascript commands then in view 2.
As a concrete example, say I have a comments controller that has the normal CRUD operations.
I now have partial called _comments_box.erb. This _comments_box.erb contains the ability to submit a comment via a simple line:
- form_for comment, :url => post_comments_path(post), :remote => true do |f|
This submits to a comments_controller.rb create method which looks somethings like this:
def create
... do some stuff, like create a new comments model
respond_to do |format|
# will respond with create.js.erb
format.js
end
end
The create.js.erb in turn adds a comment to the view, perhaps doing a bunch of other updates to the DOM.
Say I render the _comments_box.erb within a view called post_summary.erb. Now I have another view, post_detail.erb that requires the same _comments_box.erb. However the post_detail.erb requires me to update completely different divs on the DOM in response to a new comment.
I need to create a different JS response for each instantiation. So I can either:
Create an alternate controller method, say create_2. Pass in some parameter to the _comments_box.erb from post_detail.erb to the _comments_box.erb partial so it knows which controller method to fire. This will allow me to have a separate file _create_2.js.erb that will allow me to manipulate the post_detail.erb view independently.
Forget about using js.erb altogether and just use plain old AJAX and get back JSON, and handle the javascript manipulation completely on the client-side.
It seems option 1 allows me to continue to use the UJS supported by Rails which is nice. But also means I probably will be adding a lot of duplicate code everywhere which is annoying. Is there a way for me to do this elegantly while continuing to use UJS?
That's exactly the purpose of Apotomo: http://apotomo.de/
Here is it's own description:
Apotomo is a true MVC widget framework
for Rails. Widgets are based on Cells
and provide reuseable view components.
Having bubbling events, they know when
and how to update themselves via AJAX!
Working with Apotomo widgets almost
feels like developing GUI components –
in a Rails environment.
Have a try, it's great.
I'd not recommend using UJS for frontend apps: server shouldn't take care of client side business. I agree it's useful and clean but it lacks performance and thus should be kept for backend stuff (RJS will move into a gem, see here: http://weblog.rubyonrails.org/2011/4/21/jquery-new-default).
That said, back to the solutions you expose:
1) I think you won't need an extra controller, you'd just have to pass additional params in order to know from where to query came from. A hidden_field could do the trick. With this info, render the good js.erb file
format.js { if condition
render "create.js.erb"
else
render "create_2.js.erb"
end
}
2) I'd go for it and return json but you'll face the same problem: knowing from where the request comes from.
A better solution (than using a hidden_field) might be to check the request.referer in your controller action. This way you leverage the fact that each context has a unique URL, and don't have to explicitly specify another unique value when rendering your widget partial.

Doing an action in Rails without changing site

Good day...
Still a beginner question. I mostly asking to save myself hours of trial and error... I had those already and there was no result.
What I wanna do... I have a controller that has an action, of course. I want to send this action two IDs, it should make some database entry of those. No problem, the action works well.
But I don't want a view to it, I want the user to click on a link and not even leave the site. Ideally there should be some Ajax (using jQuery a lot on the site) that changes the link to a 'Thanks' or anything.
So yes, my main question is: How can I activate an action of an other controller without leaving the site, from a link. Long intro, but I hope you can give me some hints.
Take a look at link_to_remote for the view side and then you can just have your controller function render nothing => true.
To keep it un-obtrusive & return something from the controller action... I think you probably want something like:
def my_action
# your code... e.g. #model = Model.find(params[:id])
render :json => { :whatever => #model.whatever }
end
In your javascript, do what thou wilt with the returned information & prevent the default action of your hyperlink by returning false or using jQuery's prevent default functionality for the click event.
Look up link_to_remote method in rails. That should make an ajax call out to a controller function and not leave the page.

Resources