Topic: Multiple Select Helper plugin

Has anyone got any experience of this plugin?

Here's the example of it's usage from the the plugin's website:

[code=ruby]# In the model
class Person < ActiveRecord::Base
  has_and_belongs_to_many :fruits
end

# In the view
<%=
  collection_multiple_select(

Re: Multiple Select Helper plugin

mip wrote:

Also, I am using has_many :through instead of has_and_belongs_to_many is there anything I need to alter the example above?

Yes, the fruit_ids method does not exist on a has_many :through association, so you need to handle that on your own. See your other post for details.

As for the controller code, it should go in whatever action the form is submitted to. This is probably the 'create' or 'update' action.

I'm actually surprised how this works. If I were to create a collection_multiple_select helper I would do this:

# in view
<%= collection_multiple_select :person, :fruits, Fruit.find(:all), :id, :name %>

# in controller
@person.find(params[:id])
if @person.update_attributes(params[:person])
  #...
end


Maybe I'll make that sometime...

Railscasts - Free Ruby on Rails Screencasts

Re: Multiple Select Helper plugin

ryanb wrote:
mip wrote:

Also, I am using has_many :through instead of has_and_belongs_to_many is there anything I need to alter the example above?

Yes, the fruit_ids method does not exist on a has_many :through association, so you need to handle that on your own. See your other post for details.

Yep. I'd figured that out and it's working.

ryanb wrote:

As for the controller code, it should go in whatever action the form is submitted to. This is probably the 'create' or 'update' action.

I'm actually surprised how this works. If I were to create a collection_multiple_select helper I would do this:

# in view
<%= collection_multiple_select :person, :fruits, Fruit.find(:all), :id, :name %>

# in controller
@person.find(params[:id])
if @person.update_attributes(params[:person])
  #...
end


Maybe I'll make that sometime...

It correctly updates the databse without me adding the code they suggest to the controller create and update actions. When I load the edit form it doesnt show and of the boxes as checked. Where is @fruits in the view segement created? Do I need to create this myself?

Re: Multiple Select Helper plugin

mip wrote:

When I load the edit form it doesnt show and of the boxes as checked. Where is @fruits in the view segement created? Do I need to create this myself?

You can probably just use @person.fruits instead of @fruits here.

Railscasts - Free Ruby on Rails Screencasts

Re: Multiple Select Helper plugin

Hi mip, I'm the developer of the plugin, I'd try to answer the questions.

The example shown in the plugin webpage is a simple example and (as you noted) have one step missing (the @fruit array).

The verbose example should be as follows:

[code=ruby]# app/models/person.rb
class Person < ActiveRecord::Base
  has_and_belongs_to_many :fruits
end

# app/models/fruit.rb
class Fruit < ActiveRecord::Base
  has_and_belongs_to_many :fruits
end

# app/controllers/people_controller.rb
class PeopleController < ApplicationController
  def new
    @person = Person.new
    @fruits = [] # an empty array when you are creating a new person
  end
 
  def create
    @person = Person.new(params[:person])
    @fruits = (params[:fruits] or []).collect { |item| item.to_i }
  end

  def edit
    @person = Person.find(param[:id])
    @fruits = @person.fruits.map &:id
  end

  def update
    @person = Person.find(param[:id])
    @fruits = (params[:fruits] or []).collect { |item| item.to_i }
    @person.attributes = params[:person]
    @person.fruit_ids = @fruits
    @person.save
  end
end

# app/views/people/_form.rhtml
# partial used by new.rhtml and edit.rhtml
<%=
  collection_multiple_select(

Re: Multiple Select Helper plugin

yonosoytu wrote:

for has_many and has_and_belongs_to_many you can find here (I think you still have to use fruit_ids instead of fruits but maybe I'll change that).

Cool, I'll have to try it out. It doesn't really matter whether it is fruits or fruit_ids for the collection_multiple_select method. Just as long as it is consistent I guess. On second thought, fruit_ids makes more sense anyway.

Last edited by ryanb (2006-10-12 14:15:54)

Railscasts - Free Ruby on Rails Screencasts

Re: Multiple Select Helper plugin

Thanks for the help guys. I wanted to use the "has_many :through" relationship for this as I'm experimenting with adding an extra attribute to the table which links Person and Fruit.

Last edited by mip (2006-10-13 06:17:27)

Re: Multiple Select Helper plugin

How do you plan on editing the extra field, do you plan on having a text field next to each check box?

Railscasts - Free Ruby on Rails Screencasts

Re: Multiple Select Helper plugin

ryanb wrote:

How do you plan on editing the extra field, do you plan on having a text field next to each check box?

I havent decided yet smile The extra field is a boolean.

Example, in the person/fruits relationship table there is a field called favourite. This is a boolean and is set to true for one entry per person and false for the rest of that persons entries. Ideally when a person-fruit relationships is added this is done using some AJAX and the user sees a list of fruits for the person updated with a a radio box next to each fruit so the favourite can be selected. Maybe the multiple select list will have to go. As you can see I'm not too sure how I want this to work yet. I'll get back to you smile

Re: Multiple Select Helper plugin

Sounds like an interesting problem. I like interesting problems. wink

Railscasts - Free Ruby on Rails Screencasts

11

Re: Multiple Select Helper plugin

OK. So supposing I have a method of setting the favourite fruit. How do I go about writing this to the database?

Example. If I have an few entries in the person_fruits relationship table for a person and I provide the user with a drop down list of those fruits. The fruit they select should become the person favourite fruit. How would I go about this?

Re: Multiple Select Helper plugin

Is there a favourite_fruit_id column in the people table? You could do this:

<%= collection_select :person, :favourite_fruit_id, @fruits, :id, :name %>

Assuming here @fruits is set in the controller. You can then update the person as usual and the favourite_fruit_id will be set:

@person.update_attributes(params[:person])

Railscasts - Free Ruby on Rails Screencasts

13

Re: Multiple Select Helper plugin

ryanb wrote:

Is there a favourite_fruit_id column in the people table?

No. There is no favourite_fruit_id column in the people table.

Tables look like this:

people
======
id
.
.
.

fruit
=====
id
.
.
.


person_fruits
=============
id
person_id
fruit_id
favourite (boolean)

Edit: Maybe this isn't the best way to do it? Anyone suggest a better way?

Last edited by mip (2006-10-26 07:12:34)

14

Re: Multiple Select Helper plugin

Anyone got any suggestions?

I was thing of adding something like this to the People model:

class Person < ActiveRecord::Base
  has_many :fruits, :through => :person_fruits do
    def favourite_fruit
      find :first, :conditions => ['favourite = \'true\'']
    end
  end
end

Any opinions?

Last edited by mip (2006-10-26 07:13:31)

15

Re: Multiple Select Helper plugin

Cool! That works smile

But how do I set the favourite_fruit? I'm guessing I need to write another function which extends the association but I can't see how.

I think I'd need to remove all the relevant entries from person_fruits then add them back setting the favourite fruit where necessary.

Any suggestions?

Last edited by mip (2006-10-26 07:45:36)

Re: Multiple Select Helper plugin

Can a person only have one favourite fruit? I think a favourite_fruit_id column would better suit this. You could then do this kind of association:

class Person < ActiveRecord::Base
  belongs_to :favourite_fruit, :foreign_key => 'favourite_fruit_id', :class_name => 'Fruit'
end

This way you get a setter method and you can create a collection_select as I showed above.

Last edited by ryanb (2006-10-26 10:25:09)

Railscasts - Free Ruby on Rails Screencasts

17

Re: Multiple Select Helper plugin

ryanb wrote:

Can a person only have one favourite fruit? I think a favourite_fruit_id column would better suit this.

Yes one favourite fruit. Part of the reason for me designing it like this is wanted to allow for a future amendment where a persons favourite fruits were ranked. So instead of there being a boolean indicating the favourite there's be a number indicating rank. Maybe that was a stupid idea.

ryanb wrote:

You could then do this kind of association:

class Person < ActiveRecord::Base
  belongs_to :favourite_fruit, :foreign_key => 'favourite_fruit_id', :class_name => 'Fruit'
end

This way you get a setter method and you can create a collection_select as I showed above.

I can see that this would be an easier way of doing this. Would I still have:

has_many :person_fruits, :dependent => true
has_many :fruits, :through => :person_fruits

in the model?

i.e.

class Person < ActiveRecord::Base
  has_many :person_fruits, :dependent => true
  has_many :fruits, :through => :person_fruits
  belongs_to :favourite_fruit, :foreign_key => 'favourite_fruit_id', :class_name => 'Fruit'
end

Thanks for your help.

Re: Multiple Select Helper plugin

mip wrote:

class Person < ActiveRecord::Base
  has_many :person_fruits, :dependent => true
  has_many :fruits, :through => :person_fruits
  belongs_to :favourite_fruit, :foreign_key => 'favourite_fruit_id', :class_name => 'Fruit'
end

Thanks for your help.

Yep, that's correct. If you aren't sure you'll need a ranking system, etc. I would just go with this since it's the easiest thing that would work.

If you want to go with the ranking, I would look into acts_as_list in the PersonFruit model, this way you can create a little drag-and-drop fruit ranking thing.

Railscasts - Free Ruby on Rails Screencasts

19

Re: Multiple Select Helper plugin

ryanb wrote:

Yep, that's correct. If you aren't sure you'll need a ranking system, etc. I would just go with this since it's the easiest thing that would work.

If you want to go with the ranking, I would look into acts_as_list in the PersonFruit model, this way you can create a little drag-and-drop fruit ranking thing.

Cheers Ryan. I'd probably go with this method. I'll have a quick read up on acts_as_list first though.

Re: Multiple Select Helper plugin

Yeah, that should work. What error are you getting? I'm guessing "favourite_fruit" is nil, make sure it is set before calling that:

<%= person.favourite_fruit.name unless person.favourite_fruit.nil? %>

Railscasts - Free Ruby on Rails Screencasts