Rails 4 search Multiple Params - ruby-on-rails

I'm looking to search and find results if two params exist, but i'm getting sent to car_show_path, but should have results.
Model
class Car < ActiveRecord::Base
def self.search(car_number, car_model)
where(['car_number = ? AND car_model = ?', "%#{car_number}%", "%#{car_model}%"])
end
end
Controller Show
#search = Car.search(params[:car_number], params[:car_model])
if #search.present?
#search
else
redirect_to car_path, notice: "Not a valid combination"
end
Form
<%= simple_form_for :search, url: car_show_path do |f| %>
<%= f.input :car_number, :collection => #car.collect {|c| [c.number]}, :include_blank => false %>
<%= f.input :car_model, placeholder: "Car Model" %>
<%= f.button :submit, 'Generate', class: 'btn' %>
<% end %>

You are doing it wrong. If you look into the params hash generated in the server log, you can see something like this :search => {:car_model => "value", :car_number => "Value"}. That means the values of :car_model and :car_number cannot be retrieved with params[:car_model] and params[:car_number], instead you should use params[:search][:car_model] and params[:search][:car_number]
#search = Car.search(params[:search][:car_number], params[:search][:car_model])
if #search.present?
#search
else
redirect_to car_path, notice: "Not a valid combination"
end

I see the code you have provided. I believe the code you have written need some improvement. So I have re-written code which may solve your issue and bring to your goal. Here it is :
#/app/models/car.rb
class Car < ActiveRecord::Base
def self.search(cn, cm)
where('car_number = ? AND car_model = ?', cn, cm)
end
end
#/app/controllers/cars_controller.rb
class CarsController < ApplicationController
def search
#result = Car.search params[c_number], params[c_modal]
end
end
#/app/views/cars/search.html.erb
#you can generate similar form with simple_form_for
<form action="/search" method="/get" >
<input type="text" name="c_number"
<input type="text" name="c_modal">
<input type="submit" value="search">
</form>
<% if !#result.any? %>
Not a valid combination
<% end %>
<% #result.each do |r|%>
<%= r.car_number %>
<%= r.car_modal %>
<% end %>
#/config/routes.rb
get "/search" => "cars#search"
Note : Above code is best of my practice and didn't executed locally.
Hope that helps!!!

You are putting the same values into both placeholders from the query parameter that is being sent to your search method. That doesn't seem right.

Related

Ruby on Rails: new params keep showing as "permitted: false"

I've been writing a new RoR app for practice. This is a basic app that is supposed to function as a lookup page for animals.
I've been working on the Create/New functions in the controller for my page. I would like to make it so that a user can enter in an animal, and have the animal save to the SQL database. Afterwards, the page should redirect to the newly created animal page.
Here's my animals_controller.rb:
class AnimalsController < ApplicationController
def index
#animals = Animal.all
end
def show
#animal = Animal.find(params[:id])
end
def new
end
def create
# render plain: params[:animal].inspect
#animal = Animal.new(animal_params)
#animal.save
redirect_to #animal
end
private def animal_params
params.require(:animal).permit(:name, :scientific_name, :range)
end
end
Here is my views/animals/new.html.erb:
<h1> Add Animal </h1>
<%= form_for :animal, url: animals_path do |f| %>
<p>
<%= f.label :name %> <br>
<%= f.text_field :name %>
</p>
<p>
<%= f.label :scientific_name %> <br>
<%= f.text_field :scientific_name %>
</p>
<p>
<%= f.label :range %> <br>
<%= f.select :range, ['land', 'sea', 'sky', 'underground'], :prompt => 'Select One' %>
</p>
<p>
<%= f.submit %>
<p>
<% end %>
When I try to enter in a new animal, here is what I get:
<ActionController::Parameters {"name"=>"cat", "scientific_name"=>"Felis catus", "range"=>"land"} permitted: false>
I'm wondering why I keep getting "permitted:false" when I have code in animals_controller.rb that states that these params are permitted! Can anyone point out anything or give me some suggestions?
Your params should look like
<ActionController::Parameters {"animal" => {"name"=>"cat", "scientific_name"=>"Felis catus", "range"=>"land"} } permitted: false>
Also, in the form, can you change :animal to #animal.
Alternatively, you can try this
params.require(:animal).permit(:name, :scientific_name, :range).permitted?
Problem is with this line render plain: params[:animal].inspect
because you are printing/accessing params directly without permission instead use :animal_params
render plain: animal_params.inspect
this lines #animal = Animal.new(animal_params) is fine. I guess your creating process works perfectly only.

Use key in params

I am trying to build a log in system by this tutorial:
http://www.youtube.com/watch?v=h0k6DFIStFY
My form looks like this:
<!DOCTYPE html>
<div id="content">
<%= flash[:alert1] %>
<%= form_for(:sessions, :url => sessions_path , :html => {:id => "login-form"}) do |f| %>
<fieldset>
<p>
<%= label_tag :name ,"Username:" %>
<%= text_field_tag :name, params[:name] , :class => "round full-width-input", :autofocus=>true %>
</p>
<p>
<%= label_tag :password, "Password:" %>
<%= password_field_tag :password, params[:password], :class => "round full-width-input" %>
</p>
<%= submit_tag "Login", :class=> "button round blue image-right ic-right-arrow" %>
</fieldset>
<% if (flash[:status] == FALSE) %>
<br/><div class="information-box round"><%= flash[:alert] %></div>
<% end %>
<% end %>
</div> <!-- end content -->
and my controller looks like this:
class SessionsController < ApplicationController
def login
end
def create
user = User.authenticated?(params[:sessions][:name], params[:sessions][:password])
flash[:alert1] = "dummy"
if user
redirect_to '/login'
else
flash[:status] = FALSE
flash[:alert] = "Invalid username and password"
redirect_to '/login'
end
end
def new
end
end
when trying to submit, i get this error:
undefined method `[]' for nil:NilClass
in the following line:
user = User.authenticated?(params[:session][:name], params[:session][:password])
Did i use incurrectly in the session key ?
Thanks,
Gal!
I think you have some problems in your form: you are using a form_for and then in fields you are using text_field_tag.
I would correct it in something like :
<% form_for sessions .... do |f| %>
<%= f.text_field :name %>
and so forth.
This will generate the params you want in your controller
params[:sessions][:name]
params[:sessions][:password]
I would suggest you to use some gem instead of building an entire system of authentication, which can be quite tricky in terms of security. Have you taken a look at https://github.com/plataformatec/devise?
Hope it helps
It looks like you're using an external authentication gem, perhaps one of these?
https://www.ruby-toolbox.com/categories/rails_authentication
You need to include a require <gem_name> line at the top.

The action 'create' could not be found for UserVacationDaysController

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

Create missing objects before form loads in rails

I am just trying to make my form display a blank field for each item that has not yet been created. I've done this successfully using the build method for more simple forms but I'm not sure how to do it for this case. Is the strategy I'm using to do this wrong or am I making a simple syntax mistake?
Here's the basic model setup:
A Comp has many Rounds and many Teams. A Round has many Items. Each Team has only 1 Item per Round
So when the form is loaded, if a team has not already created an item, I want there to be a blank item created for that team so that it shows up in the form and can be edited for that team.
I tried 2 different methods in my controller and neither has worked:
Method 1:
def edit_admin
#comp = Comp.find(params[:comp_id])
#round = #comp.rounds.find(params[:round_id])
team_ids = #round.items.all(:select => :team_id).collect(&:team_id)
#comp.teams.each do |team|
if team_ids.include? team.id == false
new_item = #round.items.new(:team_id => team.id, :round_id => #round.id)
new_item.save
end
end
end
def update_admin
#comp = Comp.find(params[:comp_id])
#round = #comp.rounds.find(params[:round_id])
if #round.update_attributes(params[:round])
redirect_to(edit_comp_path(#comp))
else
render 'edit_admin'
end
end
Method 2:
Essentially the same thing but I defined a method to run before the page loads:
before_filter :build_new_items, :only => :edit_admin
private
def build_new_items
#comp = Comp.find(params[:comp_id])
#round = #comp.rounds.find(params[:round_id])
team_ids = #round.items.all(:select => :team_id).collect(&:team_id)
#comp.teams.each do |team|
if team_ids.include? team.id == false
new_item = #round.items.new(:team_id => team.id, :round_id => #round.id)
new_item.save
end
end
end
The form looks like this (the view is called edit_admin.html.erb):
<%= form_tag update_admin_comp_round_items_path(#comp,#round), :method => :put do %>
<% for item in #round.items.all %>
<%= "Team: " + #comp.teams.find(item.team_id).team_name %> <br />
<%= fields_for 'round[items_attributes][]', item do |f| %>
<%= f.label :item_name %>
<%= f.text_field :item_name %> <br />
<%= f.hidden_field :id, :value => item.id %> <br />
<% end %>
<% end %>
<p><%= submit_tag "Submit" %></p>
<% end %>
Thanks.
Answering my own question since no one else did: I got method B to work with a very minor tweak. All it needed was parentheses around the value after "include?", like so:
if team_ids.include?(team.id) == false.
I figured this out by playing with each line of code in the rails console.
Method A may work as well but since I got method B to work, I haven't yet tried it.
UPDATE: method A also works

Rails linking form submission to object

In a rails project I have two entities, Users and Institutions, they have a many-to-many relationship.
The views for them are set up to create new users and institutions but I want to have another view for linking the two.
In rails console all I have to do is
myuser.institutions << the_institution_i_just_created
The controller can do some of the work but how do I handle the submissions and the forms? I want to use a selection box so that the input is limited to the Institutions already in existence.
<select id="institution_selection" name="institution_sel">
<% selections = []
Institution.all.each do |institution|
pair = [institution.name, institution.id]
selections.concat([pair])
end
%>
<%= options_for_select(selections) %>
</select>
So the question in summary is how do I map this submission to an object so that in the controller I can do add it to the relation?
The solution was:
Alright, so this is the solution I came up with, I'm sure there is a better way to go about it and I'll continue to look into it but at least I got something close to what I was aiming for
def test
if !session[:user]
redirect_to users_path, notice: "Please login first"
end
if params[:institution]
#user = User.find(session[:user])
#institution = Institution.find(params[:institution][:id])
#user.institutions << #institution
redirect_to #user, notice: "Institution was successfully added "
end
end
and for the view
<%= form_tag("/users/test", :method => "post") do %>
<%= collection_select :institution, :id, Institution.all, :id, :name %>
<%= submit_tag("Search") %>
<% end %>
Use collection_select
<% from for #instancevar do |form| %>
<%= form.collection_select :institution_id, Institution.all, :id, :name %>
# Do other stuff....
<% end %>

Resources