Database driven radio button ruby on rails - ruby-on-rails

I am trying to update my conditions table with the radio button's value on and off
Here is the view
= form_tag('/admin/save',:action => 'update') do
= radio_button_tag("#{cols}_#{id}",1,checked = eval(check), options = {})
= radio_button_tag("#{cols}_#{id}",0,checked = eval(negcheck), options = {})
= submit_tag
Here is the controller
def updateCondition
params.each do |keys , value|
key ="#{keys}"
condition = key.split("_")[0]
hospitalid =key.split("_")[1]
if condition == "utf8" || condition == "authenticity" || condition == "commit"
next
end
Condition.find(hospitalid).update(:"#{condition}" => params["#{condition}_#{hospitalid}"])
end
render nothing: true
end
Params are :
{"utf8"=>"✓",
"authenticity_token"=>"",
"abc_10000"=>"1",
"commit"=>"Save changes",
"def_10000"=>"1",
}
Here is my question :
1) Why params is not showing all my radio button values ?
2) Any way to handle utf8, authentication_token, commit other than if statement ?

This may be why params not showing:
This looks strange to me: checked = eval(check) should it be checked: eval(check) or checked == eval(check)
Why are you setting options = {}? I think options should be passed in as a hash or not passed in at all.
Regarding #2,
if condition == "utf8" || condition == "authenticity" || condition == "commit"
next
end
Condition.find(hospitalid).update(:"#{condition}" => params["#{condition}_#{hospitalid}"])
You could extract that into a separate function:
def condition_valid?
condition == "utf8" || condition == "authenticity" || condition == "commit"
end

You're asking two questions here which is bad protocol for SO. I'll answer the second one.
Rather than try to filter out the parameters you don't want, which is very fragile, you could send through all the things you are trying to process, grouped into a single param. Eg, in your form, change the radio buttons to
= form_tag('/admin/save',:action => 'update') do
= radio_button_tag("conditions[#{id}][#{cols}]"}",1,checked = eval(check), options = {})
= radio_button_tag("conditions[#{id}][#{cols}]"}",0,checked = eval(negcheck), options = {})
= submit_tag
this will give you params like
{"utf8"=>"✓",
"authenticity_token"=>"",
:conditions => {1000 => {:abc => 1, :def => 1}},
"commit"=>"Save changes"
}
See how they are organised and separated? This means you don't have to muck about splitting them up again.
Now your controller code could be:
def updateCondition
params[:conditions].each do |id , attributes|
if condition = Condition.find_by_id(id)
condition.update_attributes(attributes)
end
end
render nothing: true
end
Note: you don't say what the value of "cols" is when you are building the form so i'm having to guess a bit. I think i just copied the way you are using it but shuffled it around a bit. There is almost certainly a cleaner way to build the form too.

Related

Couldn't find Employee with id when im trying to add the one more time when enter the wrong data

I am facing the problem when I am trying to edit & add the new data. In this controller I am creating the new data of the relatives with employee_id, if I want to change the relative when I added the wrongly using this code I can delete but unable to add. When I am adding it is saying could't find the employee with id.
Can any one tell where I am wrong?
def employee_relations
if params[:relative]
#employee = Employee.find(employee_relative_params[:employee_id])
#employee_relatives = Relative.where(employee_id: #employee.id, relation_type_id: params[:relative][:relation_type_id])
#employee_relatives = Relative.create!(employee_relative_params.merge!("created_by" => current_user.id)) if ((#employee_relatives.empty? && params[:relative][:relation_type_id] != '3') || ( params[:relative][:relation_type_id] == '3'))
else
#employee = Employee.find(params[:employee_id])
#employee_relatives = Relative.where(employee_id: params[:employee_id].to_i)
end
#relation_types= Masters::RELATION_TYPE
respond_with(#employee_relatives)
end
for removing the data: this is for deletion it will work perfectly. if
I pass the params here like
employee_relative = Relative.find_by_id(params[:employee_relation_id][:employee_id])
it is
throwing the nil value
def remove_employee_relation
employee_relative = Relative.find_by_id(params[:employee_relation_id])
employee_relative.destroy if employee_relative
#relation_types= Masters::RELATION_TYPE
respond_with({:msg => "success"}, :location => nil)
end
You do not have a value for employee_id. From your post:
Parameters: {"utf8"=>"✓", "relative"=>{"relation_type_id"=>"3", "relation_name"=>"DADsdsd", "date_of_birth"=>"", "sex"=>"Male", "status"=>"Alive", "employee_id"=>""}, "commit"=>"Save"}
So your employee id is not being set wherever you are setting it(I am assuming in your form).

How to accept hash parameters

Here are the parameters being passed:
{"utf8"=>"✓",
"authenticity_token"=>"j3R0aro/Arg4Y3Zu6zIIxZYbYTxqoqyKEGc11CkvYDU=",
"inventory"=>{
"9"=>"0",
"12"=>"0",
"1"=>"0",
"2"=>"0",
"3"=>"0",
"10"=>"0",
"11"=>"0",
...
}
}
I can't seem to grab the params in inventory, for whatever reason, the code below keeps wanting to grab the inventory as one long array of hashes rather than the hashes themselves. What am I doing wrong?
def inventory_params
params.permit(inventory: [{:itemlist_id => :quantity}] )
#inventory_params = params.reject { |k, v| (v == "") || ( v == "0" ) }
end
I also tried params.permit(inventory: {:itemlist_id => :quantity} ) which didn't work either
params.require(:model_name).permit(:inventory)
will work I guess.
What ended up working:
params["inventory"]

Rspec, Rails - how to test helper method that use params hash?

I want to implement a tagging system similar to stackoverflow, there is a box with a tags at top right corner, and also I have links to delete tag from params hash. my method works correctly in browser. But I can't find a way to test it.
def tags_list_with_destroy_links
if params[:tags]
li = ""
p = params[:tags].split("+") # '/tagged/sea+ship+sun' => ['sea', 'ship', 'sun']
p.map do |t|
remove_link = if p.count >= 3
c = p.reject {|item| item == t }
a = c.join("+")
{:tags => a}
elsif p.count == 2
c = p.reject {|item| item == t }
{tags: c[0]}
else
questions_url
end
li << content_tag(:li) do
link_to(t, questions_tags_path(t), class: 'tag') +
link_to( '', remove_link , class: 'icon-small icons-cross')
end
end
ul = content_tag(:ul, li.html_safe)
ul << tag(:hr)
end
end
I've tried:
it 'return list with selected tags' do
#Rails.application.routes.url_helpers.stub(:questions_tags).and_return('/questions/tagged/sea+ship+sun')
#helper.request.stub(:path).and_return('/questions/tagged/sea+ship+sun')
helper.stub(:url_for, {controller:'questions', action: 'index', tags:'sea+ship+sun'} ).and_return('/questions/tagged/sea+ship+sun')
helper.params[:tags] = 'sea+ship+sun'
helper.tags_list_with_destroy_links.should == 'list_with_tags'
end
but it return:
<a class=\"tag\" href=\"/questions/tagged/sea+ship+sun\">sea</a><a class=\"icon-small icons-cross\" href=\"/questions/tagged/sea+ship+sun\"></a></li>
and shoud return remove link as
href="/questions/tagged/ship+sun" without sea
I would appreciate any advice
The params field is going to come back parsed into the correct ruby data structures (hash, array, string, etc). There's no need to manually split items such as +, if there is a nested param it will return as part of the params object:
{tags: ["sea", "ship", "sun"]}
To access your data, or create an assumption about your param data existing in the test, you're going to want to create a stub. You're almost there, try something more along the lines of:
helper.stub!(:params).and_return({tags: ["sea", "ship", "sun"]})
Once you have the params stubbed correctly you can check the output of your helper method to ensure it's validity (this is called the expectation):
expect(helper.tags_list_with_destroy_links).to eq("some_url")

Params contain an array that wants to be a hash

I have an array (coming from a file_field, :multiple => true) in my params that I want to turn into a hash so I can build associated models for each element and process in my create action.
Currently receiving:
{"gallery"=>{"name"=>"A Gallery", "photos_attributes"=>{"0"=>{"image"=>[#<1st Image data removed for brevity>, #<2nd Image data removed for brevity>]}}}, "commit"=>"Save"}
I'd like to turn it into something like:
{"gallery"=>{"name"=>"A Gallery", "photos_attributes"=>{"0"=>{"image"=>#<1st Image data removed for brevity>}, "1"=>{"image"=>#<1st Image data removed for brevity>}}}, "commit"=>"Save"}
considered something like this but it's clearly wrong:
i = 0
params[:gallery][:photos_attributes]["0"][:image].reduce({}) do |result, element|
result[i++.to_s] = element
end
What's the "Rail's Way"?
You need to return the result hash at the end of each iteration.
i = 0
params[:gallery][:photos_attributes]["0"][:image].reduce({}) do |result, element|
result[(i += 1).to_s] = element
result
end
I've done something similar when receiving data from an iOS device. But, if I understand what you want and what your model(s) look like, to get nested attributes to work you don't want it to look like:
{ "photos_attributes" => { "0" => <image1>, "1" => <image2>, ... }
You want it to look like:
{ "photos_attributes" => [ <image1>, <image2>, ... ] }
And to do that all you need to do is:
params["gallery"]["photos_attributes"] = params["gallery"]["photos_attributes"]["0"]["image"]
Now, if I've misunderstood what you need, to get what you've asked for what you have might work (I don't use much reduce aka inject) or you could use tap:
i = 0
params["gallery"]["photos_attributes"] = {}.tap do |hash|
params["gallery"]["photos_attributes"]["0"]["image"].each do |image|
hash[i.to_s] = image
i = i + 1
end
end
Not a whole lot better IMO.

Rails: How to manipulate find(params[])

I am trying to use Object.find(params[]) to only return objects with :stage_id = integer
Here is my controller code
def show
#lesson = Lesson.find(params[:id])
#stage1 = #lesson.units(params[:stage_id] == 1)
#stage2 = #lesson.units(params[:stage_id] == 2)
Each lesson has many units, each unit has either a stage_id = 1 or stage_id = 2, I want #stage1 to become an array with units that only have a stage_id value of 1. The same goes for stage2.
How can I properly use params to return only units that have the indicated table values?
def show
#lesson = Lesson.find(params[:id])
#stage1 = #lesson.units.first(:conditions => { :stage_id => 1 })
#stage2 = #lesson.units.first(:conditions => { :stage_id => 2 })
end
Ref find
#stage1 = Unit.find(:all, :conditions => ["stage_id=? AND lession_id=?" 1, params[:id]])
#stage2 = Unit.find(:all, :conditions => ["stage_id=? AND lession_id=?" 2, params[:id]])
If Units are "always' going to be structured with Stages, one thing you could do to DRY up your code is to have a Stage model. That allows flexibility to add more stages in the future without breaking code. Assuming that relationship is properly established and data is good, you could do something like the following.
controller code
#lesson = Lesson.find(params[:id])
view code (haml)
- for stage in #lesson.stages
= stage.name
- for unit in stage.units
= unit.name

Resources