Rails route error switch local - ruby-on-rails

I'm setting my new Rails website in more than one language, and I'm having problems with the routes. I'm following the instruction of the book 'Agile web development with Rails 4'.
The browser print me this error but I can see that routes are created correctly, so:
What am I doing wrong? (At the end of this message I'll attach all my routes)
No route matches [POST] "/en/home"
When I try putting the routes directly in the browser ("localhost:3000/en" OR "localhost:3000/es") everything works OK. The error prints only when I change my language's switcher. That's why I think the routes are correctly set, and I think is a problem of my switcher or the controller...?
This is the code in the application.html.rb (basically a switcher between languages):
<%= form_tag home_path, class: 'locale' do %>
<%= select_tag 'set_locale',
options_for_select(LANGUAGES, I18n.locale.to_s),
onchange: 'this.form.submit()' %>
<%= submit_tag 'submit' %>
<%= javascript_tag "$('.locale input').hide()" %>
<% end %>
This is the configuration of my routes.rb file:
Group::Application.routes.draw do
devise_for :admin_users, ActiveAdmin::Devise.config
ActiveAdmin.routes(self)
scope '(:locale)' do
resources :posts
resources :contacts
root "posts#home"
get "/home" => "posts#home"
get "/contact" => "contacts#new"
# static pages
get "/investment" => "contents#investment"
get "/partner-with-us" => "contents#partner", as: "partner"
get "/our-companies" => "contents#companies", as: "companies"
get "/site-map" => "contents#sitemap", as: "sitemap"
get "/terms-and-conditions" => "contents#terms", as: "terms"
get "/privacy" => "contents#privacy"
end
end
This is a file created in /config/initializers/i18n.rb:
#encoding: utf-8
I18n.default_locale = :en
LANGUAGES = [
['English', 'en'],
["Español".html_safe, 'es']
]
And finally, this is the code for my posts_controller.rb, because here is where I create an action "home" in order to put the last post in the home page:
class PostsController < ApplicationController
def index
#posts = Post.all.order("created_at desc")
end
def show
#post = Post.find(params[:id])
end
def home
if params[:set_locale]
redirect_to home_url(locale: params[:set_locale])
else
#posts = Post.all.order("created_at desc")
end
end
end

try to add :method => :get to your form, like this
<%= form_tag home_path, class: 'locale', :method => :get do %>

Related

Rails 4 Params not passed to the controller from the form

I am using a form for "GET" method. I created a text field (in testing.html.erb) for user to enter the name. I want the name to be passed into the controller and based on the name, I want to retrieve his data from the database through a query.
The problem here is that I am not getting anything into the instance variable in the controller action (Nothing is printed on screen when I display #testing in "testing.html.erb"). Below is my routes.rb file.
Rails.application.routes.draw do
resources :users
# The priority is based upon order of creation: first created -> highest priority.
# See how all your routes lay out with "rake routes".
# You can have the root of your site routed with "root"
# root 'welcome#index'
# Example of regular route:
get 'index' => 'users#index'
get 'testing' => 'users#testing'
# Example of named route that can be invoked with purchase_url(id: product.id)
# get 'products/:id/purchase' => 'catalog#purchase', as: :purchase
.....
This is my testing.html.erb file
<h1> Testing page </h1>
<%= form_for users_path, :url => {:action => "testing", :name => :name}, :html => {:method => :get} do |f| %>
<%= f.label :first_name %><br />
<%= f.text_field :name %><br />
<%= f.submit "View Schedule" %>
<% end %>
<%= #testing %>
<%#= #testing.email %>
<%#= #testing.content %>
Please note that I commented #testing.email/content in above file to supress the error (undefined method `email' for nil:NilClass).
Below is my users_controller.rb file.
class UsersController < ApplicationController
before_action :set_user, only: [:show, :edit, :update, :destroy]
#before_action :user_set, only: [:testing]
# GET /users
# GET /users.json
def index
#users = User.all
#test = params[:name]
#test_index = params[:age]
end
# GET /users/1
# GET /users/1.json
def show
end
def testing
#testing = User.find_by(name: params[:name])
#if #testing.name == "Siri"
# #render text: "Hello #{#testing.name}"
#redirect_to action: :index
#end
end
.........
private
# Use callbacks to share common setup or constraints between actions.
def set_user
#user = User.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def user_params
params.require(:user).permit(:name, :email, :content)
end
end
The log-file shows the following.
Processing by UsersController#testing as HTML
Parameters: {"utf8"=>"✓", "/users"=>{"name"=>"hello rails"}, "commit"=>"View Schedule"}
I also tried to use strong params as User.find_by(name: params[:users][:name]) which throws error "undefined method `[]' for nil:NilClass".
I think I am going wrong somewhere. Please correct me. Thank you for your time.
Issue lies here:
Parameters: {"utf8"=>"✓", "/users"=>{"name"=>"hello rails"}, "commit"=>"View Schedule"}
Do you see /users key in your params? It shoudn't be there. This indicates problem with your form:
<%= form_for users_path, :url => {:action => "testing", :name => :name}, :html => {:method => :get} do |f| %>
First argument is expected to be a string (which is then used as a name of form params) or ActiveModel object. In your case, it is string returned by users_path, which is just '/users'. It should be #testing
<%= form_for #testing, :url => {:action => "testing", :name => :name}, :html => {:method => :get} do |f| %>
That will fix your current issue, you will get another shortly after that, which should go into a separate question.
You'll be best using the following:
#app/views/users/testing.html.erb
<%= #user.try(:name) %>
<%= form_tag users_testing_path, method: :get do |f| %>
<%= f.text_field :name %>
<%= f.submit "View Schedule" %>
<% end %>
This will allow:
#app/controllers/users_controller.rb
class UsersController < ApplicationController
def testing
#user = User.find_by name: params[:name]
end
end
You could improve your routes file too:
#config/routes.rb
resources :users, path: "", only: :index, path_names: { index: "index" } do #-> url.com/index
get :testing, on: :collection #-> url.com/testing
end

Disable auto redirect_to in rails app

Can I disable auto redirect in ruby on rails, here my example: In my controllers
class WelcomeController < ApplicationController
def index
#a = params[:link]
if #a != nil
Kernel.system("ls")
redirect_to root_path
else
end
end
end
I don't want to redirect to root_path and stay in current pages, so I remove redirect_to root_path, like this:
def index
#a = "abcd"
if #a != nil
Kernel.system("ls")
else
end
end
But my app still auto redirect to root_path, I don't know how to fix that, please! help me:)
my routes:
root 'welcome#index'
match '/upload', to: 'welcome#index', via: 'post'
my html:
<%= form_tag(upload_path, :id => "form_check") do %>
<%= text_field_tag :link %>
<%= submit_tag("Process")%>
<%end%>
I think your problem isn't really auto redirect. You are "redirected" to your index because this line doesn't match: match '/upload', to: 'welcome#index', via: 'post'.
What you should do is to separate index and upload. It will be far easier to manage.
routes:
root 'welcome#index'
get 'form' => 'welcome#form', as: :form_path
post 'upload' => 'welcome#upload', as: :upload_path
form page:
<%= form_tag(upload_path, :id => "form_check") do %>
<%= text_field_tag :link %>
<%= submit_tag("Process")%>
<%end%>
And then you can create your new actions inside welcome, called form and upload. The last one redirect you to /form, so you can see your form again.

Locale Switcher

I am busy going through PBP - Agile Web Development with Rails and implementing the locale switcher.
However when I try switch between english and spanish I get a error:
No route matches [POST] "/en"
My controller is as follows:
class StoreController < ApplicationController
skip_before_filter :authorize
def index
if params[:set_locale]
redirect_to store_path(locale: params[:set_locale])
else
#products = Product.order(:title)
#cart = current_cart
end
end
end
and an extract of the application.hmtl.erb that is being used;
<div id="banner">
<%= form_tag store_path, class: 'locale' do %>
<%= select_tag 'set_locale', options_for_select(LANGUAGES, I18n.locale.to_s), onchange: 'this.form.submit()' %>
<%= submit_tag 'submit' %>
<%= javascript_tag "$('.locale input').hide()" %>
<% end %>
<%= image_tag("logo.png") %>
<%= #page_title || t('.title') %>
</div>
the routing folder is as follows:
scope'(:locale)' do
resources :users
resources :orders
resources :line_items
resources :carts
resources :products do
get :who_bought, on: :member
end
root to: 'store#index', as: 'store'
end
Cant figure out what I did wrong. If I enter /en or /es in the url it works correctly. However choosing it in the drop down that is created I get the error mentioned
Found the issue, the form_tag was expecting a POST so I changed
<%= form_tag store_path, class: 'locale' do %>
to
<%= form_tag store_path, class: 'locale', :method => :get do %>
and it worked
You are missing an slash in the scope as guides states:
# config/routes.rb
scope "/:locale" do
resources :books
end
http://guides.rubyonrails.org/i18n.html#setting-the-locale-from-the-url-params

Rails: form for different controller

I'm developing a rails app with a landingpage. On the landingpage, the user can sign up for the app. For login, there is an extra view with an extra controller.
It looks like this:
views/landinpage/index.html --> sign up form
views/login/index.html --> login form
but I only want to have one controller
controllers/login_controller --> create new user from sign up form & check login data
so I have to get a connection between the landingpage view and the login_controller.
This is my attempt:
<%= form_for #login, :url => { :controller => "login_controller", :action => "create" }, :html => {:method => :post} do |f| %>
but it throws a route error:
No route matches {:controller=>"login_controller", :action=>"create"}
I already defined login resources in routes.rb, but it seems that the problem is elsewhere?
resources :logins
any ideas?
try this
class LoginsController < ApplicationController
def new
...
end
def create
...
end
...
end
in your route.rb file write
match '/login/create' => 'logins#create', :as => :create_login
or
resources :logins
in your console - write - rake routes and check your routes
then
<%= form_for #login, :url => create_login_path(#login) do |f| %>
I think your code should look like this:
<%= form_for #login, :url => { :controller => "login", :action => "create" }, :html => {:method => :post} do |f| %>
can't test this right now, but I believe the _controller part is not required.
Update:
Another thing that I'm using a lot and that works:
<%= form_for #login, :url => create_login_path(#login), :html => {:method => :post} do |f| %>
You may have to fix the create_login_path part to match your application's routes but that's how I usually define these views.
Try this
class LoginsController < ApplicationController
def new
...
end
def create
...
end
...
end
in your routes.rb file
resources :logins do
collection do
post :create
end
end
and in your views
<%= form_for #login, :url => create_login_path(#login) do |f| %>>
you can see the html form action part, you can see!
your config/routes has
resources :posts
namespace :admin do
resources :posts
end

What is wrong in "mapping" URLs to Rails actions with this form?

In 'app/views/users/reset.html.erb' file I have this code:
<%= form_tag( send_reset_users_path, :method => :post ) do %>
<%= text_field_tag :email %>
<%= submit_tag("Send") %>
<% end %>
In 'app/controllers/*users_controller.rb*' I have this code:
def reset
respond_to do |format|
format.html # reset.html.erb
end
end
def send_reset
...
end
In 'config/routes.rb' I have this code:
resources :users do
collection do
get 'reset'
get 'send_reset'
end
end
When I submit the form I get the error: "No route matches "/users/send_reset"" (browser URL becomes '.../users/send_reset'). What is wrong? How can I "map" URLs to Rails actions?
P.S.: I think the problem is in "config/routes.rb"...
the problem is here :method => :post and get 'send_reset', in my opinion you are trying to POST parameters when your conntroller expect GET method
You routes.rb declares the send_reset route as only available via get. You have to write post 'send_reset':
resources :users do
collection do
get 'reset'
post 'send_reset'
end
end

Resources