default selected radio_button in rails3 - ruby-on-rails-3

Is there a cleaner way of selecting a radio_button by default or if it was previously selected in one line of code?
I first tried this:
- if #job.new_record?
= f.radio_button :environment_id, env.id, :checked => env.is_default
- else
= f.radio_button :environment_id, env.id, :checked => #job.environment == env
I tried to refactor using this:
= f.radio_button :environment_id, env.id, :checked => (#job.andand.environment == env) || env.is_default
but the problem with that is if the default selection is AFTER the job's environment, it will select the default selection.
Any other suggestions?

I would probably just set the default value for the model in the controller. That logic should not be placed in the views. I don't know exactly how that would work for you because I don't know the structure of your models or where the "default" value comes from, but if you set the default value in the controller then the radio button will be selected if it matches the env.id in your case
# In Controller
#job = Job.new(:environment_id => "foo")
# In the view
= f.radio_button :environment_id, "foo"
= f.radio_button :environment_id, "bar"
In this case, the first radio button will be selected.

use radio_button_tag
=radio_button_tag environment_id, env.id, (#job.andand.environment == env)

Related

including rails object in meta tags keywords

I'd like to include a rails object in my keywords as well as straight text but the code is clearly not the right way to do it...how can I do this?
set_meta_tags :keywords => %w[keyword1 keyword2 #{params[:hospital]}]
You might want to have a look at two plug-ins for including rails object in meta tags:
Meta Magic: https://github.com/lassebunk/metamagic
Head Liner: https://github.com/mokolabs/headliner
Edit: For Meta tag gem
What I usually do is write a meta helper that I simply stick in my ApplicationHelper, that looks like this:
def meta(field = nil, list = [])
field = field.to_s
#meta ||= {
'robots' => ['all'],
'copyright' => ['My Copyright'],
'content-language' => ['en'],
'title' => [],
'keywords' => []
}
if field.present?
#meta[field] ||= []
case list.class
when Array then
#meta[field] += list
when String then
#meta[field] += [list]
else
#meta[field] += [list]
end
case field
when 'description' then
content = truncate(strip_tags(h(#meta[field].join(', '))), :length => 255)
else
content = #meta[field].join(', ')
end
return raw(%(<meta #{att}="#{h(field)}" content="#{h(content)}"/>))
else
tags = ''
#meta.each do |field, list|
tags += meta(field)+"\n"
end
return tags.rstrip
end
end
You can simply set meta tags in your views, by adding a call to meta() in it. So in an articles/show.html.erb you might add this to the top of your view:
<% meta(:title, #article.title) %>
And in your layouts, you add it without any parameters, so it'll spit out the meta tags.
<%= meta %>
Or have it output an individual tag:
<%= meta(:title) %>
I bet you there's more elegant solutions, though.
But if you were looking for something already implemented in Rails you're out of luck.
Thanks.
Try this in your view as it worked for me (using meta-tags gem):
<% keywords [[#modelname.keyword1], [#modelname.keyword2]] %>
and you cad additional keywords in text format by adding them within the ruby in the following format ['keyword3']

Can I add logic to a rails 3 hidden field?

I have a form to submit data and I want to automatically set one field depending on whether all the other fields are filled out or not. If they are all completed, the field will be "complete", if not it will be set to "draft".
So I have the hidden field like this:
<%= f.hidden_field :status, :value => "draft" %>
to make it default to draft. BUT, can I add logic that says it will be "complete" if all the other fields are filled out and if so how?
Here is how to do it on the client-side with jquery, assuming your model is named foo:
<script type='text/javascript'>
$(document).ready(function() {
$('input[name*="otherfields"]').on('change', function() {
var othercount = 0;
$('input[name*="otherfields"]').each(function() {
if ( $(this).is(':checked') )
othercount += 1;
});
if ( othercount == 2 )
$('#foo_status').attr('checked',true)
else
$('#foo_status').attr('checked',false)
});
});
</script>
<%= check_box_tag :item1 , '1', false, :name=>'otherfields[1]' %>
<%= check_box_tag :item2 , '2', false, :name=>'otherfields[2]' %>
<%= f.hidden_field :status, :value => "draft" %>
Assuming no other client-side events have to take place when the the status changes, it would be best practice to place this kind of business logic inside of your model as a callback, e.g. (replace Foo and fieldx with your model and field names):
class Foo < ActiveRecord::Base
before_save :default_status
def default_status
if field1 && field2 && field3 && field4
self.status = 'completed'
else
self.status = 'draft'
end
end
end
Yes, you can do that in the controller.
Lets say the form directs you to the create action.
In the create action of the controller, you can check if all the fields are completed by looking at params and then use if statement to assign appropriate value to status before saving
This would be done with javascript, possibly jQuery. However, why would you design it this way? Could you not do this on the server side?

Selected option not working for select

I have this select which works fine, but default the select is empty and doesn't show the selected value (which is filled correctly):
<%= f.select(:relationgroup, options_for_select(#relationgroups), { :selected => #relation.relationgroup, :include_blank => true}) %>
Any idea why? Thanks!
Try it that way:
<%= f.select(
:relationgroup,
options_for_select(#relationgroups, #relation.relationgroup),
:include_blank => true
) %>
Not sure, but maybe it'll work better.
Anyway, assuming Relationgroup is some model with id and name (or any other attribute that you want to be visible in select options) attributes, and you're using default relationgroup_id foreign key in your model you'd better construct your select like that:
<% f.select(
:relationgroup_id,
options_from_collection_for_select(#relationgroups, :id, :name),
:include_blank => true
) %>
It'll choose selected value based on object.relationgroup_id where object is the model you're building form for. See docs for more information.

Rails 3: Controller params default value

I am using a remote form_for for my show action to retrieve content based on the params passed by this form.
= form_tag modelname_path(#modelname), :id=>"select_content_form", :remote => true, :method => 'get' do
= text_field_tag :content_type, params[:content_type], :id=>"select_content_type"
= submit_tag "submit", :name => nil, :id=>"select_content_submit"
And I alter the content in controller as follows:
# Default params to "type1" for initial load
if params[:content_type]
#content_type = params[:content_type];
else
#content_type = "type1"
end
case #content_type
when "type1"
# get the content
#model_content = ...
when "type1"
# get the content
#model_content = ...
My question is, whether the above approach is the only we can set defaults for params or can we do it in a better manner. This works but I would like to know if this is the right approach.
UPDATE
Based on the suggestion below, I used the following and got an error on defaults.merge line:
defaults = {:content_type=>"type1"}
params = defaults.merge(params)
#content_type = params[:content_type]
A good way of setting default options is to have them in a hash, and merge your incoming options onto it. In the code below, defaults.merge(params) will overwrite any values from the params hash over the default ones.
def controller_method
defaults = {:content=>"Default Content", :content_type=>"type1"}
params = defaults.merge(params)
# now any blank params have default values
#content_type = params[:content_type]
case #content_type
when "type1"
#model_content = "Type One Content"
when "type2"
#etc etc etc
end
end
If there is a static list of types you could make it a dropdown box and just don't include a blank option so that something is always selected. But if you're stuck with a textbox you could clean up the controller action by using a before filter:
class FoosController < ActionController::Base
before_filter :set_content_type, :only => [:foo_action]
def foo_action
...
end
protected
def set_content_type
params[:content_type] ||= "type1"
end
end
I wanted to add to this discussion a working way to set default params:
defaults = { foo: 'a', bar: 'b' }
params.replace(defaults.merge(params))
This avoids assigning a local variable via "params =".

Rails 3/3.1 and I18n: Validation hits when switching between languages

The database is seeded with values in english language and format, e.g., :hourlyrate => 20.90. On first start (language is english by default), the input form displays the content of the field correctly. I can modify and save, no problem.
If I switch to german, the number is displayed correctly as 20,90. If I edit anything on this form, I can not save again, as the validation catches the number as not being valid.
My question is, do I have to perform corrections in my controller before saving, or did I miss some built-in function of Rails?
Relevant parts of the code
Helper:
def my_number_with_precision(value)
if value
# value
number_with_precision(value, :precision => 2)
end
end
Validation:
validates :hourlyrate, :numericality => { :greater_or_equal_than => 0, :message => " is an invalid number or below zero" }
Form:
<div class="input">
<%= f.text_field :hourlyrate, :value => my_number_with_precision(f.object.hourlyrate) %>
</div>
Gemfile
gem 'rails-i18n'
I came up with one of the following solutions - language specific code:
def parse_i18n(value)
if I18n.locale = 'de'
value.gsub(',', '.')
else
value
end
end
def parse_i18n(value)
value.gsub(I18n.t("number.currency.format.unit"),'').
gsub(I18n.t("number.currency.format.delimiter"), '').
gsub(I18n.t("number.currency.format.separator"), '.')
end