Add URL parameters on successful create method - ruby-on-rails

Case:
When I submit my form that is located on /jobs/test-lune-f/apply?locale=fr the create method gets launched and does some checks.
The code will either run trough the whole create method and go the the create.html.erb page or will do return render :index.
Problem:
The problem is that the create.html.erb has the same URL /jobs/test-lune-f/apply?locale=fr as the index.html.erb page.
Question:
When the create method runs completely ok, is it possible to an URL parameter like #success to it?
I've tried to do this via the addition of :anchor => "success" to the form_for but it also get's added when the method returns via return render :index.
Goal:
To be able to add URL parameters when the form get's submitted successfully.
CODE:
Routes:
resources :jobs, :only => [:show, :index, :create] do
resources :apply, :only => [:index, :create]
resources :share, :only => [:index, :create]
end
resources :apply, :only => :index do
collection { get 'add'}
end

You have to change the location before rendering the page:
location=location()+(location().include?'?' '&' : '?') +"status=success"
More info about api location.

I was trying to do it with Rails but as mentioned the most easy fix is in jQuery.
<script>
$(document).ready(function() {
location.hash = "success";
});
</script>

Related

Why does form_for helper require index path for a new action

I have the following in my routes file
resources :details, only: [:show, :edit, :update, :new]
and in new.html.erb
<%= form_for(#detail) do |f| %>
<%= render 'fields', f: f %>
<% end -%>
and in the details controller
def new
#detail = Detail.new
end
When the new.html.erb is rendered, I get the following error message
undefined method `details_path' for #<#<Class:0x007fc4ac6bd730>:0x007fc4b62e7390>
What is causing this?
The cause of this is that the the form_for helper is looking to post to /details. So it is not looking for the index path but the :create path.
So you need to add the :create action to your routes declaration
resources :details, only: [:show, :edit, :update, :new, :create]
If you look at the rendered html in this case, it will look like this
<form class="new_detail" id="new_detail" action="/details" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓" />
so you can see why you need the :create path which makes the post /details path.
The create and index actions use the same path but different actions. So if you have either in the routes file, then a details_path method will be generated. In your case you want to make sure you have the create in your routes file:
resources :details, only: [:create, :show, :edit, :update, :new]
To give context to your answer, you need to look up about the resourceful nature of Rails' routes:
Browsers request pages from Rails by making a request for a URL using a specific HTTP method, such as GET, POST, PATCH, PUT and DELETE. Each method is a request to perform an operation on the resource. A resource route maps a number of related requests to actions in a single controller.
When you say... "form_for helper is looking to post to /details", it's actually looking to post your form data to the create method. The way it does this is through the POST verb on the /details route:
Thus, you need to ensure that you're declaring your create route if you wish to use the resourceful routing structure.
This is why you'll need the following:
#config/routes.rb
resources :details, only: [:show, :edit, :update, :new, :create]
or
resources :details, except: :index
--
Of course, you don't have to use it.
You can use whichever routes you want. The important thing, though, is to understand that Rails is built around convention; HTTP's is towards resources:
The server, which provides resources such as HTML files and other content, or performs other functions on behalf of the client, returns a response message to the client
This is why you have "resourceful" routing etc.
On top of Rails' object orientated nature, you need to appreciate which resources are being used at certain points in your app.
form_for expects a new object to route to the create route. You can override this by using the url: option:
<%= form_for #object, url: none_resourceful_path ...

Can I get a controller to show up in the url under a different name?

I have a controller called "Pages". Can I make it show up in the url bar under a different name? For example, when I render the 'show' template, it shows up under this url: localhost:3000/pages/:id. Could I make it show up as localhost:3000/people/:id? I only care about the 'show' url; the other urls aren't that important.
routes.rb
get "pages/results"
get "pages/index" => "pages#index", as: "index_page"
resources :pages do
resources :categories
end
Add this your routes:
get '/people/:id', to: 'pages#show'
And remove the old show route from the resource:
resources :pages, only: [:index, :new, :create, :edit, :update, :delete] do
resources :categories
end
See: Rails guides about rounting
You could use like this:
get '/pages/:id' => "pages#show", path: 'people/:id'
This way you can access particular show page in the browser.
Hope this helps you.

Adding member or alias to existing path in Rails 3

For the jobs -> apply action I want to "alias" the "create" action.
In rake routes it would look something like this:
https://gist.github.com/YOUConsulting/19b404759757898a6f4f#file-rake_routes-rb
I've tried to do it like this but I think this is not exactly what I'm looking for:
resources :jobs, :only => [:show, :index, :create] do
resources :apply, :only => [:index, :create] do
member do
post :completed
end
end
resources :share, :only => [:index, :create]
end
In human words:
When the user submits the page located at "/jobs/<job_id_here>/apply" (the index view) the result page (the create view) should be "/jobs/<job_id_here>/apply/completed" instead of "/jobs/<job_id_here>/apply/" .
Reason:
When we track users via Google Analytics we can't see if they submitted the form successfully since there is no difference between "/apply" and "/apply" .
Hm, what about using a named route as path
Add a line at the end of your routes.rb
post '/jobs/:job_id/apply/completed', to: apply#create as: apply_job
And then in your new.html.haml
form_for :job, apply_job_path
This should call the create action of your apply controller.
Instead of apply you can use of course any name you want.

Rails 4 and Coffeescript Simple Ajax return html

I have a simple Coffeescript method calling a controllers action:
retrieveFeedData: (selected) ->
$.post 'demo_feeds',
feed_title: selected.text()
feed_url: selected.val()
(data) -> $('body').append data
Here is the route I created:
post :demo_feeds, to: 'feeds#demo_feeds', as: 'demo_feeds'
Here is the Rails method:
def demo_feeds
if request.xhr?
# respond to Ajax request
else
# respond to normal request
end
end
How do I return the content of the actions view file and pass it back to the data variable in Coffeescript?
EDIT:
I also found that feeds controller also has some resources setup:
resources :feeds, only: [:index, :edit, :create, :update] do
resources :entries, only: [:index], controller: :feeds_entries
collection do
get :view_unread
get :view_all
get :auto_update
end
end
Is there a way to work around this without messing up the resource?
Just had to add remove the layout and things worked fine:
def demo_feeds
render :layout => nil
end

Overriding a resource route to / (root) in Rails3: not changing the path helper?

I am quite new to Rails3, I basically created a subscribers scaffolding, I only want my app to respond to new and create actions.
So in config/routes.rb I defined:
resources :subscribers, :only => [:new, :create]
Which works this way
GET /subscribers => subscribers#new
POST /subscribers => subscribers#create
Now I want my app to exhibit the subscribers resources at / (root) instead of /subscribers, so here is what I did:
match '/' => "subscribers#new"
match '/' => "subscribers#create"
match '/' => "subscribers#thankyou"
resources :subscribers, :only => [:new, :create]
Which somehow works, but is probably not the DRYest thing: here are the issues I have:
When going back to the form after an issue on a create the browser displays the /subscribers URL instead of just /, the form is created using the form_for(#subscriber) helper method, so the path helper must be somehow unaffected by the route
Ideally I don't even want the app to respond to a request on /subscribers
I noticed a weird bug, when posting the form while disconnected (from /, and then doing a refresh when the connection comes back (browser ask for resubmitting => OK), the Rails app crashes (I don't have the error stack though as this was on production), why is that?
Also, I tried setting up the route this way:
resources :subscribers, :only => [:new, :create] do
collection do
post '/' => :create
get '/' => :new
end
end
Which is probably DRYer, but it doesn't fix any of these issues.
I am sure this is something quite simple, please help!
Thank you for your answers, it helped me find the exact solution to my question:
resources :subscribers, :only => [:new, :create], :path => '', :path_names => {:new => ''}
Tested and working on Rails 3 :)
You could do
resources :subscribers, :path => ''
and make sure that GET / is being served by your root template, e.g. by adding this to SubscribersController:
def index
render 'welcome/index'
end
I experimented with using a match "/" declaration to override the resource index action and map it to another controller instead but apparently a resources declaration is always fully overriding manually declared routes.
For number 2 in your list, delete this line, and rewrite any _path or _url methods in your erb:
resources :subscribers, :only => [:new, :create]

Resources