Condition with params rails - ruby-on-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

Related

Is it possible to put multiple conditions in a th:classappend attribute

I've been racking my brains on this for a while and I'm pretty sure I'm getting the syntax wrong.
Basically I have a <div> and want it to have the class="hidden" unless two thymeleaf conditions are met.
I want the class 'hidden' unless there's an error present on the input.
This works on it's own:
th:classappend="${#fields.hasErrors('month') == false} ? 'hidden'
I want the class hidden unless the value of the input is not null.
This works on it's own:
th:classappend="${applicationData.month == null} ? 'hidden'"
Is there anyway to concat these two conditions into one th:classappend? I'm struggling with getting that working at the moment. Something like this doesn't seem to work for me
<div id="date-met" class="date-container" th:classappend="${#fields.hasErrors('month') == false} ? 'hidden' || ${applicationData.month == null} ? 'hidden'" >
<input id="month" name="month" type="text" th:value="${applicationData.month}">
</div>
Thanks in advance and apologies if it's a stupid question!
You can use:
( condition_one || condition_two ) ? 'hidden'
So in your case that would be:
th:classappend="${ ( #fields.hasErrors('month') == false || applicationData.month == null ) ? 'hidden' }">
The parentheses may not even be necessary - just added for clarity.

Filtering in Ruby on Rails

I have an Ruby on Rails application in which I have the following resources pets, pet types, vaccinations(the event of vaccinating a pet) and persons. So, pet belongs to a type (a type has many pets) and vaccination belongs to a pet (a pet can have many vaccinations). What I want to do is the following: To have a collapsable list (a select) o all the pet types with a submit button in the vaccinations index, so that I can filter vaccinations by pet types. My code is the following:
This is the index method in the vaccination controler:
def index
if params[:type_id]
flash[:notice] = "Post successfully created"
#vaccinations = Vaccination.filter(params[:type_id])
else
#vaccinations = Vaccination.all
end
end
This is the search form in the vaccinations index:
<form action="/vaccinations" method="GET">
<%= #type_id %>
<select name="type_id">
<option disabled selected value> Select a classification </option>
<% Type.all.each_with_index do | t, index | %>
<option value="<%= t.id %>" <% t.id.to_s == #type_id ? "selected" : "" %>> <%= t.name%> </option>
<% end -%>
</select>
<input type="submit", value="SUBMIT" />
</form>
And this is my filter method in the vaccination model, the one that I call in the controller.
def self.filter(type_id)
t = Array.new
for v in Vaccination.all
if type_id == v.pet.type.id
t.push(v)
end
end
t
end
What happens is that when I don´t select any pet type, I can see every vaccination as it should be. But when I select any pet type, no matter the type of the pets that have been through a vaccination, it doesn´t show me anything. If i have made three vaccinations to cats an select cat, and filter, it shows me nothing as if I didn´t have any vaccinations. That´s my problem. Sorry for my english, it´s not my first language!
The correct way of doing it is through relationships.
Example ( should work fine, didn't test it ):
def self.filter(type_id)
Vaccination.joins(pet: :pet_type).where(
pet_types: {
id: type_id
}
)
end
Now you will get a list of vaccinations of all the pets with the sent type.

Remove HTML tag attribute in slim when attribute should not be displayed

I would like to remove class attribute when class should not be displayed in Slim.
In ERB, I could use:
<input <%= "class='foo'" if false %> />
<input />
How do I do this in Slim?
I found this, but I feel there must be a more idiomatic solution:
| <input "#{'class=\"foo\"' if false}" />
If the value of an attribute is nil, then the entire attribute will be omitted (actually this is happens for nil or false for most cases, but it looks like the class attribute behaves differently for false and true):
input class=('foo' if condition)
This will output
<input class="foo" />
if condition is true, and
<input />
if condition is false.
You can use the splat (*) operator to help define conditional attributes for tags in slim, using hashes containing the attributes to be added.
http://www.rubydoc.info/gems/slim/frames#Splat_attributes__
The splat operator will expand a hash into a set of attributes to be added to the tag. If the hash is empty, no attributes will be added.
For example,
- admin_classes = #User.admin? ? {class: "foo"} : {}
input *admin_classes
if #User.admin? == true, it should render
<input class="foo">
else if #User.admin? == false, it should render
<input>
For attributes like "class" or other attributes that have attribute merging turned on, you can also do something like this:
- admin_classes = #User.admin? ? {class: ["foo","bar"]} : {}
input *admin_classes class="biz"
if #User.admin? == true, it should render
<input class="foo bar biz">
else if #User.admin? == false, it should render
<input class="biz">

Validation of Input 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

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