I have a form where a user can CRUD a task and assign it to another user via the form. I currently am using the pluck method to get the full array of users. Naturally, I want to exclude the current user from this list.
My current code in task > _form.html.erb is as follows:
<%= f.select :assignee, User.pluck(:email), :prompt => "Select one" %>
It's difficult to figure out what to do since User.pluck(:email) provides a full array that is hard to exclude values from. Appreciate any suggestions, ideally that can be done in this field rather than in the controller.
Thanks!
You can do this by using where and passing conditions to exclude the current_user
<%= f.select :assignee, User.where("id <> ?", current_user.id).pluck(:email), :prompt => "Select one" %>
You could add a where condition:
<%= f.select :assignee, User.where('id != ?', current_user.id).pluck(:email), :prompt => "Select one" %>
Related
My form contains the following tag:
<%= f.collection_select :employee_id, #employees, :id, :value, :prompt => true %>
Employee looks like this:
employee
- attr1
- attr2
- user
- firstname
- lastname
My question: How to set the lastname of an employee as the value in the select field? I'm pretty sure it's possible, but I think I have some gaps in the syntax.
Why would you do that?
It's possible, with:
<%= f.collection_select :employee_id, #employees, :last_name, :text_method, :prompt => true %>
Where :text_method is method which called on #employees members will return text that you'd like to appear in dropdown.
You may be asking yourself why I have used <%= f.select %> this is FormOptionHelper on the Ruby on Rails Api this is very similar to collection_select however with that it returns and tags for the collection of values. Whereas select creates a series of contained option tags for provided object and method. So in saying this I believe you could have the following:
<%= f.select(:employee_id, Employee.all.collect { |emp| [emp.lastname, user.id] }
.sort{ |a, b| a[0] <=> b[0] }, {:prompt => "Select a Employee"}) %>
This selects all employees and sorts them in order of their last name.
I've got 3 models that comprise a has-many-through association.
Model code as follows:
ItemAttrVal Model (the transition table)
class ItemAttrVal < ActiveRecord::Base
belongs_to :attr_name
belongs_to :registry_item
end
RegistryItem Model
class RegistryItem < ActiveRecord::Base
has_many :item_attr_vals
has_many :attr_names, :through => :item_attr_vals
accepts_nested_attributes_for :item_attr_vals, :allow_destroy => :true
end
AttrName Model
class AttrName < ActiveRecord::Base
has_many :item_attr_vals
has_many :registry_items, :through => :item_attr_vals
end
The RegistryItem uses a fields_for as follows:
<%= item.fields_for :item_attr_vals do |iav| %>
<%= render 'item_attr_val_fields', :f => iav %>
<% end %>
In the partial, it looks like this:
<% logger.debug "object type is: #{f.object}"%>
<% logger.debug "some details are: #{f.object.attr_name_id}--"%>
<%= f.select :attr_name_id, options_from_collection_for_select(AttrName.all,"id","description"), :selected => f.object.attr_name_id, :prompt => "Select an attribute" %>
<%= f.text_field :raw_value %> <br />
The 1st 2 debug lines are the bit that my question is about, but it first relates to the 3rd line.
There, I am attempting to provide the dropdown select field with a "pre-selected" value. This is so that when the user is editing the RegistryItem, their previously selected AttrName will be displayed.
I'm attempting to use the f.object.attr_name_id to set that value, however it does not actually properly select the previously selected value, and instead, just goes to the 1st.
The 1st two debug lines were then me trying to make sure that my f.object method worked...
When I looked in my logs, I see the following:
object type is: #<ItemAttrVal:0x007fb3ba2bd980>
some details are: --
Basically, the 1st line shows me that I am getting the ItemAttrVal
The second line does not seem to retrieve any information for it.
I've also used the debugger to check, and in there, I am able to use display f.object.attr_name_id to show me the exact value that I'm expecting...
This kind of comes down to two questions...
Why can't I retrieve the values of f.object?
Am I trying to do line 3 (<%= f.select :attr_name_id, options_from_collection_for_select(AttrName.all,"id","description"), :selected => f.object.attr_name_id, :prompt => "Select an attribute" %>) wrong, and there's actually a better way to do it?
Thanks in advance!
you need to use params[:attr_name_id] into your options_from_collection_for_select
<%= f.select :attr_name_id, options_from_collection_for_select(AttrName.all,"id","description", params[:attr_name_id].to_i), :prompt => "Select an attribute" %>
hope it helps
Turns out I'd placed the :selected in the wrong location...
Original:
<%= f.select :attr_name_id, options_from_collection_for_select(AttrName.all,"id","description"), :selected => f.object.attr_name_id, :prompt => "Select an attribute" %>
Should be:
<%= f.select :attr_name_id, options_from_collection_for_select(AttrName.all,"id","description", f.object.attr_name_id), :prompt => "Select an attribute" %>
Fixing that solved my problem, the attribute names are now appearing as expected for previously saved attributes.
It still doesn't answer my original query about why I'm not able to get the values for f.object printed out, but at least the original-original problem was resolved.
I have a Box which has many Items which belongs to a Category.
When the Box is created it has the user_id.
Items has a category_id.
I've seen that if you have a user_id in the table concerned it works okay:
<%= f.collection_select :category_id, Category.where(:user_id => current_user.id), :id , :name %>
But how can I get a Category collection_select from what the current_user has entered - do I have to add a user_id to Categories or can I join my tables somehow?
Maybe this way is easier:
<%= f.collection_select :category_id, current_user.categories, :id, :name %>
PS: Even better if you put this in your controller, so, in case you have to change the select and add some clauses, you will not need to change almost all your views, just the controller (MVC).
I have a select tag nested in my form and I am needing to delete an item from my options_for_select array if it equals the word English
code:
<%= fields_for :users_languages do |u| %>
<div class="field">
<%= u.label :Assign_Languages %><br />
<%= select_tag :language_id,
options_for_select(Language.all.collect {|lang|
[lang.english, lang.id].delete_if {lang.english == "English"}
}, #lang_list),
:multiple => true,
:prompt => 'Select Language' %>
</div>
<% end %>
Problem:
The above code works fine, but for some reason the first option is still shown in the mutli-select producing a blank select option. Is there anyway to get rid of the select option and its value? Am I even doing this correctly?
Thanks for all the help in advance!
You can do it using a collect and a reject.
Language.all.collect { |lang| [lang.english, lang.id] }.reject { |(lang, id)| lang == 'English' }
Not sure how to do it using just collect.
I realize this is a year old, but for the sake of future googlers...
Rather than inlining SQL, you might be better off with a named scope:
scope :not_english, where("english != 'English'") # Rails 3
or
named_scope :not_english, :conditions => "english != 'English'" # Rails 2
which will let you do:
options_for_select(Language.not_english.collect {|lang| [lang.english, lang.id]})
That is easier to read, more expressive, and not depending on some magic database id.
Cheers!
(PS: Also, you may want to consider updating your schema so the name of the db column isn't confused with it's value. May I suggest language.name, rather than language.english?)
It looks like your selection is actually returning an empty array as the first element. Try pulling out the unwanted option first:
Language.all.reject {|lang| lang.english == "English}.collect {|lang| [lang.english, lang.id]}
Thanks for the reply guys! What I ended up doing was handle it in my query
code:
<%= fields_for :users_languages do |u| %>
<div class="field">
<%= u.label :Assign_Languages %><br />
<%= select_tag :language_id, options_for_select(Language.find(:all, :conditions => "id != 1").collect {|lang| [lang.english, lang.id]}, #lang_list),:multiple => true, :prompt => 'Select Language' %>
</div>
<% end %>
the first row in the database will always be the same so this was easy to do in the query... although the suggestions above will come in handy in the future! Thanks again!
I'm trying to create a <select> element using the collection_select method, but it seems that in order for the proper <option> to be selected, the identifier passed into collection_select needs to be an instance variable and not a local variable (this is happening in a partial).
So when I create a <select> for the categories of a product, the proper category is NOT selected by default.
_product_row.erb (DOES NOT WORK):
My product: <%= product.name %>
<%= collection_select(:product, :category_id, #current_user.categories, :id, :name, options = {:prompt => "-- Select a category --"}) %>
Screenshot:
alt text http://img534.imageshack.us/img534/8929/screenshot20100421at120.png
I discovered that I was able to get it to work by declaring an instance variable before hand, but this seems like a huge hack to me.
_product_row.erb (WORKS):
<% #product_select_tmp = product %>
<%= collection_select(:product_select_tmp, :category_id, #current_user.categories, :id, :name, options = {:prompt => "-- Select a category --"}) %>
Screenshot:
alt text http://img534.imageshack.us/img534/1958/screenshot20100421at120l.png
Because this partial is iterating over a collection of products, I can't just have #product declared in the controller (IOW unless I'm missing something, product must be a local variable in this partial).
So how do I get collection_select to select the appropriate item when calling it with a local variable?
Have you tried passing in the :selected key in the options hash? If you provide it with the current product.id it should behave the way you're expecting.
<%= collection_select(:product, :category_id, #current_user.categories, :id, :name, {:prompt => "-- Select a category --", :selected => product.category.id}) %>
You can pass collections to partials and designate a local variable to pass them as:
<%= render :partial => "products/product_row", :collection => #products, :as => :products %>
Relevant documentation: http://apidock.com/rails/ActionView/Partials