I've seen this question asked everywhere, but it never solves my problem. Heres my controller:
class UserVacationDaysController < ApplicationController
def new
#user = current_user
#user_vacation_days = UserVacationDay.new
end
def create
#user_vacation_days = UserVacationDay.create(params[:user_vacation_day])
#user_vacation_days.user = current_user
# #user_vacation_days.calculate_work_days
# (another param that holds date range will get passed in)
# puts #user_vacation_days.errors.inspect
if #user_vacation_days.persisted?
flash[:notice] = "Request Sent"
redirect_to dashboard_index_path
request_vacation_days # method from model. model method calls method in employee_mailer
else
flash[:notice] = "Something went wrong, please try again"
render :new
end
end
end
And here is my view (form).
<h2>Request Days Off</h2>
<%= form_for :user_vacation_days, :url => user_vacation_days_path do |f| %>
<div><%= f.label "How much time off would you like to take?" %>
<%= f.number_field :number_of_days %></div>
<div><%= f.label "Argue your case, slave" %>
<%= f.text_area :description %></div>
<div><%= f.submit "Request Time Off" %></div>
<% end %>
The routes for my 2 controller methods are
user_vacation_days POST /user_vacation_days(.:format) user_vacation_days#create
new_user_vacation_day GET /user_vacation_days/new(.:format) user_vacation_days#new
Does anyone have any idea what's going on? I've looked all over the place, and I can't find anything. I can't think of any reason why the controller method wouldn't be found. Thanks!
Instead of <%= form_for :user_vacation_days, :url => user_vacation_days_path do |f| %> what happens if you use <%= form_for #user_vacation_days, :url => user_vacation_days_path do |f| %>
Also, does a User have_many VacationDay? You might want to change to resourceful routes, and have vacation days nested.
config/routes.rb
resources :users do
resources :user_vacation_days
end
in your new action under UserVacationDaysContoller #may want to rename this to just VacationDays since the nesting implies
def new
#user = current_user
#user_vacation_days = #user.vacation_days.build
end
Related
This is my first ror app.
I have main page: home.html.erb
I have form there.
<%= form_for(#lead ,:html => {:class => 'check_form'}) do |f| %>
<%= f.text_field :phone, placeholder: 'phone' %>
<%= f.submit "Check car status", class: "btn btn-large btn-primary" %>
<% end %>
Backstory: a customer(I call him Lead can input his phone number and check status of his car which is being repaired now.)
Right now this view home.html.erbis served by static_pages_controller
class StaticPagesController < ApplicationController
def home
#lead = Lead.new()
end
def help
end
def about
end
def contact
end
end
I have also LeadsController
class LeadsController < ApplicationController
*some code*
def create
#lead = Lead.new(lead_params)
if #lead.save
#sign_in #lead
flash[:success] = "Request successfully created!"
redirect_to #lead
else
render 'new'
end
end
* some code
end
What I want to do when user inputs his phone number to find lead in database with the same phone number and show repair status to user.
So back to my problem:
I know how to find lead by phone like this Lead.find(params[:id])
But where to write this code? I need to find lead by phone and then print it to screen. How can I do this?
What I want to do when user inputs his phone number to find lead in
database with the same phone number and show repair status to user.
Currently your form serves the wrong purpose. This requires a form with GET request. I'll be doing it by declaring a custom route like below
get :check_lead_car_status, to: 'static_pages#check_lead_car_status', as: 'check_lead_car_status'
And in the static_pages#check_lead_car_status
def check_lead_car_status
#lead = Lead.find_by(phone: params[:phone]
end
And modify the existing form like below
<%= form_tag check_lead_car_status_path, :method => :get do %>
<%= text_field_tag :phone, placeholder: 'phone' %>
<%= submit_tag "Check car status", class: "btn btn-large btn-primary" %>
<% end %>
And a page check_lead_car_status.html.erb with the below code
The Status of the Car is: <%= #lead.status %>
youre redirecting to #lead which means should be the show path in the lead controller. which means you need to put that logic in a method called show in your Lead controller
then in your view (views/leads/show.html.erb) you can access that variable
edit:
if all youre trying to do is query by a different parameter, then you should look into the active record query interface. specifically section 1.1.5
Lead.find_by(phone: params[:phone])
I'm having a trouble when I'm trying to user params.require(...).permit(...)
In my application I received the follow param dic:
{"utf8"=>"✓",
"authenticity_token"=>"Vatzcb5tgTu2+wL1t6Of+FbIK8Ibp+tM03Naai4b2OU=",
"/login"=>{"username_or_email"=>"jonatasteixeira",
"password"=>"[FILTERED]"},
"commit"=>"Save /login" }
I would like to know why the my key received the "/login" name.
My view:
<h1>Login</h1>
<%= form_for(login_path) do |f| %>
<div class="field">
<%= f.label :username_or_email %><br>
<%= f.text_field :username_or_email %>
</div>
<div class="field">
<%= f.label :password %><br>
<%= f.password_field :password %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
<%= link_to 'Back', root_path %>
In my controller
class SessionsController < ApplicationController
# GET /login
def new
#user = User.new
end
# POST /login
def create
#user = User.find_by_emai(session_params[:username_or_email]) || User.find_by_username(session_params[:username_or_email])
if #user && #user.authenticate(session_params[:password])
session[:current_user_id] = #user.id
flash[:notice] = 'You are logged in'
else
flash[:notice] = 'Invalid password, username or email'
end
end
private
# Never trust parameters from the scary internet, only allow the white list through.
def session_params
logger.info :login
params.require("/login").permit(:username_or_email, :password)
end
end
I dont want to use "/login" as key, I would like to use :login. Some one knows how could I adjust it?
Thanks!!
As #Rafal pointed out, you could code your call to form_for like this to get rid of the awkward /login key in your params:
<%= form_for(:login) do |f| %>
Strong parameters are really only for scenarios where you are doing mass assignment on an object. If you were creating the user, for example, then you would probably want to pass the attributes into the new initializer method using strong parameters.
#user = User.new(session_params)
But because you're not doing mass assignment in this case, you can just pass in the values directly without a session_params method:
# POST /login
def create
#user = User.find_by(email: params[:login][:username_or_email]) || User.find_by(username: params[:login][:username_or_email])
if #user && #user.authenticate(params[:login][:password])
session[:current_user_id] = #user.id
flash[:notice] = 'You are logged in'
else
flash[:notice] = 'Invalid password, username or email'
end
end
The whole point of strong parameters is so no one can pass in extra attributes. In your /login scenario, your code is completely in control of the values being handled, so you don't need to worry about it.
Form_For
When you use form_for, Rails expects an object to be passed so it can build a variety of different elements from it:
[The form_for] helper is designed to make working with resources much easier
compared to using vanilla HTML.
The problem is you're passing a route to this method, which I'm surprised actually works.
--
form_tag
You'll be better using a symbol, as recommended by the accepted answer, or by using form_tag, which doesn't require an object:
<%= form_tag login_path do %>
<%= text_field_tag :username_or_email %>
<%= password_field_tag :password %>
<%= submit_button_tag "Go" %>
<% end %>
This will remove the references to the "login" key of your params, and will give you the ability to do this (no need for require):
params.permit(:username_or_email, :password)
Instead of
<%= form_for(login_path) do |f| %>
use
<%= form_for(:login) do |f| %>
How do you route a resource to its controller? I am using the resource in an edit page for a different model, so my actions are being routed to its model controller first.
This edit page requests from
class Grandstreamers::ResellersController < ApplicationController
def new
end etc...
I am trying to route the requests to here instead:
Grandstreamers::CertificatesController < ApplicationController
def new
end
def update
end etc...
This is my form under views/grandstreamers/resellers/edit.html.erb
<%= form_for #untrained, :url => certificates_update_path(#untrained) do |f| %>
<p> Trained Users </p>
<%= select_tag "certificate[user_id]", options_for_select(#current_trained.collect{|x| [x.name, x.id]}), {:multiple => :multiple} %>
<%= f.submit "Un-Train", class: "btn btn-large btn-primary" %>
<% end %>
<%= form_for #trained, :url => certificates_create_path(#trained) do |f| %>
<p> Non-Trained Users </p>
<%= select_tag "certificate[user_id]", options_for_select(#non_trained.collect{|x| [x.name, x.id]}), {:multiple => :multiple} %>
<%= f.submit "Train", class: "btn btn-large btn-primary" %>
<% end %>
My route is:
resources :certificates
Note that the
:url => certificates_create_path
is not correct and not working. Is there a way to specify this route in my routes.rb file or in my form? Thank you
EDIT
This is my resellers_controller edit() which is routes to first.
#trained = Certificate.new(params[:certificate])
#Trying to get to certificates_controller update. Then update the :attend to "No"
##untrained = Certificate.new(params[:certificate])
##untrained = Certificate.find(params[:id])
##untrained = Certificate.find_by_user_id(params[:id])
#untrained is not defined, I am not sure how to get it to just go to my certificate controller. For #trained I can define it since its not made yet and does not give me errors when it cant find a correct value.
My certificates controller which uses create() but cannot get to update()
def create
#trained = Certificate.new(params[:certificate])
if #trained.save
#trained.update_attributes(attend: "Yes")
end
redirect_to grandstreamers_resellers_path
end
def update
#untrained = Certificate.find(params[:id])
#untrained.update_attributes(attend: "No")
redirect_to grandstreamers_resellers_path
end
Major Issue
The instance variable #trained and #untrained need to be defined somehow in reseller_controller. What can I define them as to load the edit page?
Part Solution
I defined this is in my resellers_controller and it loads the edit page now.
#untrained = User.find(params[:id])
Now I get this error:
No route matches [PUT] "/certificates.1"
I believe the problem is you need to let routing know the full name to the controller.
From the Rails routing guide:
scope module: 'Grandstreamers' do
resources :certificates
end
Use these paths when creating the form:
<%= form_for #untrained, :url => certificate_path(#untrained), :method => :put do |f| %>
<%= form_for #trained, :url => certificates_path, :method => :post do |f| %>
use this his routes.rb file
namespace :grandstreamers do
resources :certificates
end
I have an app and I have nested routes like so
resources :teams, shallow: true do
resources :texts
resources :translations
end
here is my app/texts.show.html.erb.My app has texts and each text has a translation and each translation belongs to a text.When I click on a text I am taken to the texts show page where I have a form for a translator.The translator can translate the text.Each translation and text belongs to a team so that I can show specific texts and translations for specific teams.However the form below seems to be doing a get request for the index action.That is the error I am getting and I can't figure out why.Maybe something very obvious I am missing.
<% if current_user.translator %>
<%= form_for [#team, #translation] do |f| %>
<%= f.text_area :translation_text, :placeholder => 'Çeviri' %>
<%= f.hidden_field :text_id, :value => params[:id] %>
<%= f.submit 'Çevir', class: 'btn btn-primary' %>
<%end%>
<%end%>
Here is my translations_controller.rb file
def create
team = Team.find(params[:team_id])
#translation = team.translations.new(translation_params)
#translation.user_id = current_user.id
if #translation.save
redirect_to request.original_url, success: 'Çeviri tamalandı'
else
redirect_to request.original_url, danger: 'Çeviri sırasında sorun oluştu lütfen tekrar dene'
end
end
private
def translation_params
params.require(:translation).permit(:team_id, :text_id, :translation_text)
end
Could the problem be that I am in texts#show and am doing something wrong with the form?
I decided to start a little project in rails 3 and I am a little bit stuck on a form... Where can I specified the f.submit action should go to a special controller / action ?
The code in the form is:
<%= form_for #user, :url => { :action => "login" } do |f| %>
<div class="field">
<%= f.text_field :email %><br />
<%= f.text_field :password %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
User is defined as #user = User.new in "index" method of "home_controller".
but I have the error:
No route matches {:controller=>"home", :action=>"login"}
as soon as I run http://0.0.0.0:3000
I am very sorry for this newbee question but I cannot find the routing details (I worked a little bit with rails a couple of years ago but...)
Thanks,
Luc
You don't need to specify any action for f.sumbit.
First of all, you need to make sure you put
resources :users
(for example)
in your routes.rb
then if you want to create a user
put
def new
#user = User.new
end
in your users_controller so you have a page to create new user
or you can put #user=User.new anywhere you like, remember to set
the route correctly
then
def create
#user = User.new(params[:id])
if #user.save
sign_in #user
redirect_to #user
else
render 'new'
end
end
is the part that does real work after you hit on submit
the actual part that connect your form with everything else is this line
<% form_for #user do |f| %>
you can change user to other object, and you can also edit form using update action in a controller.
Hope you got the idea
Whenever you use REST objects, the mere:
form_for #article
is enough for the form to find the proper path.
Otherwise, you can use helpers this way:
form_tag(:controller => "people", :action => "search", :method => "get", :class => "nifty_form")
More info here: http://edgeguides.rubyonrails.org/form_helpers.html