Validation of Input Rails - ruby-on-rails

i created a simple search input form for a Rails application, but i noticed that when i dont input anything it returns a result of all my users, but i dont want it to work when no value is placed
My form
<h6>Search for Friends</h6>
<form action ="users/search" method="post">
<input name = "key" type="input" />
<input value="Search" type="submit"/>
</form>
Controller method
def search
#users = User.find(:all,:order => 'username', :conditions => ["username LIKE ?", "%#{params[:key]}%"])
end

Try the new Arel writing or check if the key was assigned.
def search
#users = User.where(["username LIKE ?", "%#{params[:key]}%"]).order('username')
end
or
def search
if params[:key].blank?
#users = []
else
#users = User.where(["username LIKE ?", "%#{params[:key]}%"]).order('username')
end
end

Related

Condition with params rails

What is wrong?
I have a form with radio buttons.
Form sends checked ids[] to create action.
I see value of params in the console, but attributes don't update.
Always assigns 9
<input name="ids[]" value="1" type="radio" class="multiradio">
<input name="ids[]" value="2" type="radio" class="multiradio">
<input name="ids[]" value="3" type="radio" class="multiradio">
p params[:ids]
#advert = Advert.new(advert_params)
if (params[:ids] == "1")
#advert.update(category: "1")
elsif (params[:ids] == "2")
#advert.update(category: "2")
elsif (params[:ids] == 3)
#advert.update(category: "3")
else
#advert.update(category: "9")
end
I think a lot is wrong to be honest... this is not exactly the way how you create checkboxes in Rails. Have you checked the form helper? Or considered using Simple Form gem?
The way you create the form:
#assuming you have a related model called category
simple_form_for #advert do |f|
= f.association :category, as: :checkboxes
Then in the controller you simply whitelist the param and save the model:
def update
#advert.update(advert_params)
end
def advert_params
params.require(:advert).permit(category_ids: [])
end
If i understood you correctly, you have a problem of setting the category value in #advert.
according to ruby syntax you have to shift your code inside blocks, that's mean you should have written your conditions like this:
if (params[:ids] == "1")
#advert.update(category: "1")
elsif (params[:ids] == "2")
#advert.update(category: "2")
elsif (params[:ids] == 3)
#advert.update(category: "3")
else
#advert.update(category: "9")
end
take a look here.
furthermore, i would recommend you to use switch case in that case

How to search multiple models with ransack in liquid templates

I am trying to implement ransack search for 3 models in a rails app that has liquid templates in the view. So far, I have been able to implement the search for just one model.
In my search controller, i have;
class SearchController < ApplicationController
def index
#courses = Course.ransack(params[:q])
# #teachers = Teacher.ransack(params[:q])
# #articles = Article.ransack(params[:q])
end
end
My search.html.liquid is empty since I want the search bar to show up in the navbar. So in my navbar.html.liquid, i included this;
<form class="search" method="get" action="{{ request.url_helpers.courses_path }}">
<input type="text" placeholder="Search" name="q[title_cont]" value="" />
<input type="submit" value="Search" />
</form>
In my routes.rb, i have
resources :search, only: [:index]
Like I mentioned earlier, the search works for the Course model but i would like to include the Teacher and Article model as well. For the Teacher model, i would like to search for field "firstname_cont" and "title_cont" for the Article model.
How do I combine the search for all 3 models in one search form that works well with liquid templates?
This answer is pertinent to the ransack portion as I have no experience with liquid and it does not seem to pertain the the question at hand
I am assuming the following
class Course < ApplicationRecord
belongs_to :teacher
has_many :articles
end
You should be able to use a compound attribute chain like title_or_teacher_firstname_or_articles_title_cont e.g.
<form class="search" method="get" action="{{ request.url_helpers.courses_path }}">
<input type="text" placeholder="Search" name="q[title_or_teacher_firstname_or_articles_title_cont]" value="" />
<input type="submit" value="Search" />
</form>
Also your controller code is traditionally represented as:
class SearchController < ApplicationController
def index
#q = Course.ransack(params[:q])
#courses = #q.result
end
end

How to wrap incoming params with a specific attribute in rails?

if I have a manually created html form with the following input field
<input type="text" name="email">
it gives the following params {"email" => "123" }
How can I wrap it with message_fields without specifying it inside the form?
eg without the following
<input type="text" name="message_fields[:email]">
So I just want to wrap my params with message_fields from my controller.
controller strong params
params.permit(:comment, message_fields: {})
The idea is to assign all incoming params to message_fields
which is t.hstore "message_fields"
"message_fields"=>{":email"=>"qew"}"
had to do the following but there definitely should be something better
fields = #mailbox.allowed_fields.gsub(" ", "").split(",")
h = {}
fields.each do |f|
h[f] = params[f]
end
attrs = message_params.tap do |p|
p["message_fields"] = h
end
then I just pass attr to create meth insted of message_params.

How to use sort_by or order_by on view and controller with will_paginate?

In my rails application I am limiting the amount of rooms displayed on a page through pagination, I want to allow the user to order/sort the results to different columns of the room model. I think I will need a drop down menu to do this, and then pass this data over to my rooms_controller maybe through an instance variable.
How can I sort the rooms with the select tag according to a column and what do I need to do in the corresponding controller to make this work?
At the moment I am using this for a drop down menu:
index.html.erb
...
...
<%= will_paginate #rooms %>
<div id="order-by">
<select>
<option value="asc">Distance</option>
<option value="asc">Name</option>
<option value="asc">Price (low to high)</option>
<option value="des">Price (high to low)</option>
<option value="asc">Reviews</option>
</select>
</div>
rooms_controller.rb
...
...
def index
#rooms = Room.paginate :page => params[:page], :per_page => 12
end
...
My room model has listing_name:string, address: string, nightly_price:integer and has_many reviews. My review model belongs_to room. I am using geocoder gem for the location of an room.
I have searched allot and tried multiple things to make this work and I can not figure this one out. For any hints on how to solve this I would be really happy!
If you need further information just let me know.
Something like:
index.html.erb
<%= will_paginate #rooms %>
<div id="order-by">
<form>
<select name="sort">
<option value="distance">Distance</option>
<option value="name">Name</option>
<option value="price">Price (low to high)</option>
<option value="price desc">Price (high to low)</option>
<option value="review">Reviews</option>
</select>
<input type="submit" value="Sort"/>
</form>
</div>
rooms_controller.rb
def index
#rooms = Room.order(params[:sort]).paginate(page: params[:page], per_page: 12)
end
Also need to ensure that params[:sort] is included into only available values,
e.g.:
sort = params[:sort]
sort = nil unless sort.in?(['distance', 'name', 'price', 'price desc', 'review'])
#rooms = Room.order(sort).paginate(page: params[:page], per_page: 12)
Consider to use separate scope for sorting or some gem. e.g. ransack

Indexed multi-value params in rails

I have a form like
<input name="url[0]" type="text" />
<input name="url[1]" type="text" />
<input name="url[2]" type="text" />
I would like to be able to access these like:
params[:url].each do |url|
# work
end
I know that if I remove the explicit index from the name, this will work, but I would prefer to keep the index in. Is this something supported by rails out of the box?
You need to modify your block like so:
params[:url].each do |index, url|
# work
end
params[:url] will be an hash like this:
params[:url]
=> {'0' => 'url-1', '1' => 'url-2', '2' => 'url-3'}
So you have to iterate over the hash like this:
params[:url].each do |key, value|
# work
end

Resources