Learner
Learner

Reputation: 4636

rails collection_select skip null values?

Table: age_values

id | kids_age | teen_age  | old_age

1  | Age - 1  | Age - 16  | null

2  | Age - 2  | Age - 17  | Age - 25

3  | Age - 3  | Age - 18  | null

4  | Age - 4  | Age - 19  | Age - 26

5  | under 5  | Age - 20  | Age - 28

I have a table age_values and model for the table is

class AgeValue < ActiveRecord::Base
  self.table_name = 'age_values
  self.primary_key = 'id

  def to_s
    kids_age
  end

  def to_s_teen
    teen_age
  end

  def to_s_old
    old_age
  end

end

in my view,

# some_condition = 5

<% if some_condition = 1 %>
  <% age = to_s %>
<% elsif some_condition = 2 %>
  <% age = to_s_teen %>
<% else %>
  <% age = to_s_old %>
<% end %>

<%= f.collection_select(age_value_for_question, :id, age, {include_blank: ((some_variable || 0) != 1) ? 'Please select an option' : false}, {name: some_name}) %>

I want to display the option which is not null. Basically for old_age just want to display {id: 2, old_age: Age - 25, id: 4, old_age: Age - 26, id: 5, old_age: Age - 28}

What I have Tried:

I have changed and added another method in my model

def to_s_old
  exclude_null_for_old_age
end

def exclude_null_for_old_age
  age = AgeValue.where("old_age IS NOT NULL")
  age.pluck(:old_age)
end

I Want to exclude the null of value 1 and 3)

My current result:

<option value=1>["Age - 25", "Age - 26", "Age - 28"]</option>
<option value=2>["Age - 25", "Age - 26", "Age - 28"]</option>
<option value=3>["Age - 25", "Age - 26", "Age - 28"]</option>
<option value=4>["Age - 25", "Age - 26", "Age - 28"]</option>
<option value=1>["Age - 25", "Age - 26", "Age - 28"]</option>

My Expected result:

<option value=2>Age - 25</option>
<option value=4>Age - 26</option>
<option value=5>Age - 28</option>

Upvotes: 0

Views: 963

Answers (2)

Dimitri
Dimitri

Reputation: 1

If you need to be able to reset selection:

f.input :ptype, collection: PROC_TYPES, label: 'Service Type', include_blank: 'None'

Otherwise:

f.input :ptype, collection: PROC_TYPES, label: 'Service Type', include_blank: false

Upvotes: 0

smathy
smathy

Reputation: 27961

First, make the method in your AgeValue model into a scope (basically a class method, so it can be called on the class itself):

class AgeValue < ActiveRecord::Base
  scope :old_ages, -> { where.not old_age: nil }

  # ... other model stuff
end

And then use that in your view:

f.collection_select :age_value_id, AgeValue.old_ages, :id, :old_age

Done.

Update

Btw, there are many things wrong with your code that I didn't mention, but that will trip you up:

  1. Your self.table_name assignment doesn't close the single quote.
  2. Your self.primary_key assignment is the same.
  3. Neither of those are actually required, because both are the default values ActiveRecord would set anyway.
  4. <% if some_condition = 1 %> will always be true because it's an assignment (using =) not a boolean test (using ==)
  5. <% age = to_s %> to_s here is being called on the implicit self which will be some weird view instance.
  6. Even if you called it on the model (eg. @age_value.to_s) it will return you the value of kids_age not the label :kids_age so when you use it in f.collection_select as you seem to be, then Rails won't be able to call that method anyway.
  7. That doesn't even matter because collection_select expects the name of the field it's assigning to first, then the collection, then the value method and then the text/display method, so four args - you seem to have missed an arg and so nothing will be called correctly anyway.

So, in summary, this code is never going to work and has so many serious problems that I don't believe it's actually working as you've pasted it, but even with typos fixed it still has serious issues.

Upvotes: 2

Related Questions