Ruby on Rails: Dealing with many-to-many relationships in one view

Hello,

I am creating an application to learn Rails and I've come to a point that I really can;t find any help on.

I have a many-to-many relationship between SHOW and ARTIST associated by APPEARANCE.
I have it all set up to Create SHOWs, ARTISTs, and then join them with APPEARANCEs (scaffolding-style), but as a workflow it doesn't seem like it would fly in actual practice.

While creating a SHOW, I'd like to also be able to add as many APPEARANCES as I want (we'll say 3 here to simplify it).  So I imagine the view looking like:
1) All the NEW SHOW information
2) 3 dropdown controls populated by ARTISTS
---When this screen is finally saved, the Create method should create the appropriate APPEARANCE records.  

On my own after this works, I'm hoping that I'll be able to apply the same technique to create new ARTIST records from the NEW SHOW view.  But again, if I get some help just with the part above, I should be able to figure it out from there... although I am feeling really incompetent right now.

Any help or insight will be greatly appreciated.

Thanks,

Mark
cmgtechAsked:
Who is Participating?
 
Geert BormansConnect With a Mentor Information ArchitectCommented:
Hi Mark

there is an article here
http://wiki.rubyonrails.org/rails/pages/Beginner+Howto+on+has_many+:through
but I don't like it, since it has its proprietary link table, and I assume you want a default link table

I gave it some thoughts, and here is how I would get started

show model
---------------
class Show < ActiveRecord::Base
      has_and_belongs_to_many:artists
end

artist model
----------------
class Artist < ActiveRecord::Base
      has_and_belongs_to_many:shows
end

controller for artist
----------------------
...
  def new
    @artist = Artist.new
    @shows = Show.find_all
  end
...

new.rhtml
------------
<h1>New artist</h1>

<% form_tag :action => 'create' do %>
<p><select name="artist[appears_in]">
        <% @shows.each do |show| %>
              <option value="<%= show.id %>">
                    <%= show.title %>
              </option>
        <% end %>
  </select></p>

  <%= render :partial => 'form' %>
  <%= submit_tag "Create" %>
<% end %>

all you need to do then is make sure that the appears_in= method exists in the model
so you need to extend the artist model

class Artist < ActiveRecord::Base
      has_and_belongs_to_many:shows
      
      def appears_in= showid
            shows << Show.find(showid)
      end
end

this will definitely work,
but I am afraid that the link will be stored in the link table
prior to the actual storage of the new artist
(which in the end could lead to erroneous links)

I have to think a bit about this,
but it gives you something to get started

maybe you need to work with stub methods in the artist model
that only get written on-save

I definitely think that writeable methods in the model are the safest solution
... certainly a lot less annoying than the method in the referenced article

weird, I never really came accross this, and there is hardly any literature about it :-(

cheers

Geert


0
 
cmgtechAuthor Commented:
I have found a good video tutorial website that does good one-to-many tutorial, I'll work on that to see if I can extned it to work with many-to-many... though any help is still apreciated.

http://railscasts.com/episodes/73 -part 1
http://railscasts.com/episodes/74 -part 2
http://railscasts.com/episodes/75 -part 3

Thanks,

Mark
0
 
cmgtechAuthor Commented:
Yeah, I was surprised at how hard it was to find documentation on it.

Your solution worked out for me though, thanks for answering such a stale question.

Thanks,

Mark
0
 
Geert BormansInformation ArchitectCommented:
welcome
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.