I am using the monologue gem and trying to create an email list signup form on one of the monologue pages. Here is the code:
<%= form_for EmailList.new, url: email_lists_path, remote: true, class: 'form-horizontal' do |f| %>
<%= f.text_field :email, id: 'userid', class: 'form-control input-medium email-field', placeholder: 'email', required: "" %>
<%= f.submit "Sign In", class: 'btn btn-success' %>
<% end %>
and here is how the route is defined when i run rake routes:
email_lists POST /email_lists(.:format) email_lists#create
So it should be working but instead I get this error:
undefined local variable or method `email_lists_path' for #<#<Class:0x007fdddf519a40>:0x007fdde482bd78>
It has something to do with how the monologue engine is mounted:
mount Monologue::Engine, at: '/blog'
Any way, how do I add routes that work within the blog?
Related
I have a search bar available on every page of the webapp by adding
<body>
<%= form_tag(class_data_index_path, :method => "get", id: "search-form") do %>
<%= text_field_tag :search, params[:search], placeholder: "Search your major" %>
<%= submit_tag "Search", :name => nil %>
<% end %>
<%= yield %>
in application.html.erb.
When I search, it shows the results, but it also navigates to /class_data?search=SearchKeyword. I want the results to show up on the current page, whether it'd be /home, /anothermodel.
How can I achieve this?
You want to use a remote form with <%= form_tag remote: true %> - see Rails form_tag remote example as an example and a starting point.
My problem is that when i try to call a specified method from a simple_form_for form it doesn't work.
Here is my code :
<%= simple_form_for #user, :url => {:action => :register_iban}, :html => { :method => :post } do |f| %>
<div class="col-md-8">
<%= f.input :first_name, :label => t('user-show.payment.form.first_name'), placeholder: "Prénom" %>
<%= f.input :last_name, :label => t('user-show.payment.form.last_name'), placeholder: "Nom" %>
<%= f.input :iban, :label => t('user-show.payment.form.iban'), placeholder: "IBAN" %>
<%= f.input :bic, :label => t('user-show.payment.form.bic'), placeholder: "BIC" %>
</div>
<div class="col-md-8 text-center">
<%= f.submit t('user-show.payment.title'), class: 'btn btn-danger' %>
</div>
<% end %>
So, as you can see, i try to call register_iban method from my user controller.
But when i do that, i have an error : No route matches {:action=>"register_iban", :controller=>"users", :id=>"5", :locale=>nil}
Everytime i create a new method in a controller, i have to create a route in the routes.rb file ? Here, i'd like to make this url : /users/5/register_iban (where "5" is the user id) call my method.
Sorry but i start in ruby and i'm pretty stuck :/
in your config/routes.rb try to add in the users resources
resources users do
member do
post :register_iban
end
end
No route matches {:action=>"register_iban", :controller=>"users", :id=>"5", :locale=>nil}
This error means you're trying to access a route which doesn't exist.
The routes are defined at config/routes.rb:
#config/routes.rb
resources :users do
post :register_iban
end
This will allow you to call the register_iban method in the users controller through your form.
You'll also want to make sure you're calling routes with the appropriate helpers:
<%= simple_form_for #user, url: user_register_iban(#user) %>
Using Simple Form For, I have created a custom auth system.
routes.rb
get '/users/sign_in' => 'sessions#new', as: :sessions_new_user
post '/users/sign_in' => 'sessions#create', as: :sessions_create_user
match '/users/sign_out' => 'sessions#destroy', as: :sessions_destroy_user, via: :delete
get '/users/process_login' => 'sessions#process_login', as: :sessions_process_login
new.html.erb
<%= simple_form_for :user do |f| %>
<%= f.input :login, placeholder: "Login", label_html: { class: 'form-control' }%>
<%= f.input :password, label_html: { class: 'form-control' } %>
<%= f.submit "Log in", class: 'btn btn-lg btn-primary btn-block' %>
<% end %>
This issue is when i run the tests to simulate a sign in, I get this error.
user visits root of application
Failure/Error: click_on 'Log in'
ActionController::RoutingError:
No route matches [POST] "/"
user_spec.rb
scenario 'user visits root of application' do
visit root_path
expect(page).to have_content("Sign in to continue")
fill_in ' Login', with: ENV['NTUSERNAME']
fill_in ' Password', with: ENV['NTPASSWORD']
click_on 'Log in'
end
This works fine in development. I cant figure it out.
Firstly, if you are learning Rails I'd recommend you start out with the simple form helpers, as you can more clearly define what you're looking for. Since you are not using RESTful routes, you'll have to define everything by hand and are really missing out on Rails's approach of convention over configuration.
However, if you really want to make Simple Form work, here's how you would do it:
<%= simple_form_for :user, url: sessions_create_user, method: :post do |f| %>
<%= f.input :login, placeholder: "Login", label_html: { class: 'form-control' }%>
<%= f.input :password, label_html: { class: 'form-control' } %>
<%= f.submit "Log in", class: 'btn btn-lg btn-primary btn-block' %>
<% end %>
Also be aware that since you are not using an ActiveRecord-backed object (just a label), you'll have to be careful to match your expected params to what Simple Form is sending in. I'm also curious as to how you have SF render out the correct action path for a user session in development without specifying it out...
because simple_form_for don't have url, it will use the current url to submit data
Not tested but I think as below:
In development, when you visit root, it will redirect to /users/sign_in, posting to /users/sign_in is acceptable
In rspec, redirecting not change the current url, it still root_path, so posting to / is invalid
Nested forms are not allowed...
I had accidentally nested a form tag with an action of "#". It all worked in development as the browser spotted it was a nested form, and it was ignoring the tag. But when I ran a rack test it failed with No route matches [POST] “/” - it also did work when I used JS/selenium test as it was being run in a real browser.
<%= simple_form_for #user do |f| %>
<form action="#" method="POST">
<%= f.input :login %>
<%= f.input :password %>
<%= f.submit "Log in" %>
</form>
<% end %>
I'm using nested resources, and in order to make a new Round, you need to have the id of its Case, so my routes.rb includes the following:
resources :cases do
resources :rounds
end
So, when a user hits the 'new round' button on the homepage, it first directs them to a page where they can pick a case that the round belongs to, before redirecting to the round form.
For the pick_case view, I have the following:
<%= form_tag new_case_round_path, method: :get do |f| %>
<%= f.select_tag :case_id,
options_for_select(Case.all.collect { |c| [c.title, c.id] }),
class: "chosen-select" %><br/>
<%= f.submit_tag "Create round", class: "btn btn-primary" %>
<% end %>
However, rails forces me to name a case_id in the new_case_round_path, so it gives me this error before it loads the pick_case view:
No route matches {:action=>"new", :controller=>"rounds"} missing required keys: [:case_id]
How can I reference the route that the form needs to submit to when the required information for the route is being entered in the form?
No route matches {:action=>"new", :controller=>"rounds"} missing
required keys: [:case_id]
The error clearly says that case_id is missing. Rails expects case_id to be present which can't be provided in your situation as you are creating a new case instance.
One way to resolve your situation is to use Shallow Nesting which provides the route for new case
resources :cases do
resources :rounds, shallow :true
end
Now, when you run rake routes, you will find a route for new case as below
new_case GET /cases/new(.:format) cases#new
So that in your pick_case view, you can change the form to
<%= form_tag new_case_path, method: :get do |f| %>
<%= f.select_tag :case_id,
options_for_select(Case.all.collect { |c| [c.title, c.id] }),
class: "chosen-select" %><br/>
<%= f.submit_tag "Create round", class: "btn btn-primary" %>
<% end %>
Which creates a case instance first before redirecting to the round form
A bit of a work-around for the answer, I feel like there's probably a more elegant way. I added post 'get_case' => rounds#get_case to routes.rb
I added this to my rounds controller:
def get_case
id = params[:case_id]
if id
redirect_to new_case_round_path(case_id: id)
else
flash[:danger] = "An error occured. Please try again"
redirect_to pick_case_path
end
end
And this is my new pick_case view:
<%= form_tag get_case_path do %>
<%= select_tag :case_id,
options_for_select(map_with_id(Case, :title)),
class: "chosen-select" %><br/>
<%= submit_tag "Create round", class: "btn btn-primary" %>
<% end %>
I have a form in Rails
<div class="page-header">
<h3>Create Blah</h3>
</div>
<%= simple_form_for #blah do |f| %>
<%= f.input :id %>
<%= f.input :name %>
<%= f.input :pho %>
<%= f.input :fun %>
<%= f.submit :class => 'btn btn-primary' %>
<% end %>
<br>
When I click the submit button, where does the code attempt to go? Does it call the create method for blah_controller.rb? Because currently, I get a routing error
Routing Error
uninitialized constant BlahsController
Here is the BlahController#create method:
def create
authorize! :create, :blahs
#blah = Blah.new(params[:blah])
if #blah.save
redirect_to admin_blah_path(#blah), :notice => 'New blah created!'
else
render :new
end
end
In my rake routes, I have
admin_blahs GET /admin/blahs(.:format) admin/blahs#index
POST /admin/blahs(.:format) admin/blahs#create
new_admin_blah GET /admin/blahs/new(.:format) admin/blahs#new
edit_admin_blah GET /admin/blahs/:id/edit(.:format) admin/blahs#edit
admin_blah GET /admin/blahs/:id(.:format) admin/blahs#show
PUT /admin/blahs/:id(.:format) admin/blahs#update
DELETE /admin/blahs/:id(.:format) admin/blahs#destroy
It looks like your BlahsController is a namespaced controller, living under the Admin module (i.e., its fully-qualified name is Admin::BlahsController). If so, when constructing forms you must also provide the :admin namespace, using something like the following:
<%= simple_form_for [:admin, #blah] do |f| %>
See the Rails Guide to Form Helpers, under the "Dealing with Namespaces" section.