SitePoint Sponsor

User Tag List

Results 1 to 9 of 9
  1. #1
    SitePoint Zealot ricklach's Avatar
    Join Date
    Nov 2004
    Location
    Victoria BC
    Posts
    116
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    One to Many Tables Problem

    I have a person table and a membership table. One person can have many membership entries in the membership table which has an id as primary key and person_id as foreign key. In the person.rb I have "belongs_to :membership" and in the membership.rb I have "has_many :people". In the controller edit method, I want to get all rows from the membership table where person_id = id of the person table. The syntax I have is
    Code:
    @membership = Membership.find(:all, :conditions => [ "person_id = ?", params[:id]])
    but this does not work - can you help me with this syntax?

    Second, once I have a membership object, how do I iterate through the object to display the various rows of the membership table?

    Rick

  2. #2
    SitePoint Zealot
    Join Date
    Feb 2003
    Location
    Mexico City
    Posts
    122
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You have the relationship backwards. A person has_may memberships, and a membership belongs_to person.

    For your second question, I suggest you use the scaffold generator, so you can see how Rails does it. Example:

    In the controller:
    Code:
    @person = Person.find @params['id'], :include => 'memberships'
    In the view:
    Code:
    <% @person.memberships.each do |m| %>
    Column a: <%= m.column_a %><br />
    Column b: <%= m.column_b %>
    etc.
    <% end %>
    Hope that helps.

    Ivan V.

  3. #3
    SitePoint Zealot ricklach's Avatar
    Join Date
    Nov 2004
    Location
    Victoria BC
    Posts
    116
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yes that does help tremendously. However, I am still having some syntax problems. On the person form I have an icon and link to open the membership form like so:
    Code:
    <%= link_to_image "new", :controller=>"memberships", :action=>"new", :id=> @params[:id] %>
    What I am trying to do is pass the id of the person from the "person edit" screen so that I can plug it into the person_id of the membership table. Because I know so little about ror at this stage I am probably trying to do it the way you would with php and not ror. So in the membership controller I have
    Code:
    def new
        @membership = Membership.new
        
      end
    
      def create
        @membership = Membership.new(params[:membership])
        @membership.type = get_setting('app_type')
        @membership.updated_by = 3  # add user id when implemented
        if @membership.save
          flash[:notice] = 'Membership was successfully created.'
          redirect_to :controller=> 'person', :action => 'edit', :id => membership.person_id 
        else
          render :action => 'new'
        end
      end
    Now you can probably see that this doesn't work as I anticipated. In addition, like php, I would like to open the membership screen in a popup, fill in the details, save and close the popup and refresh the person edit screen. I am open to any suggestions regarding a better way of doing this but perhaps we could do it in stages. This methodology is one I use in my php application frequently so I would like to keep it if at all possible and solving this one solves a dozen others. Your assistance is deeply appreciated.

    Rick

  4. #4
    SitePoint Zealot
    Join Date
    Feb 2003
    Location
    Mexico City
    Posts
    122
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The first code you might want to change to:
    Code:
    <%= link_to image_tag('new'), :controller => 'memberships', :action => 'new', :person_id => @params[:id] %>
    Then, on your memberships controller:

    Code:
    def create
    person = Person.find(@params[:person_id])
    person.build_membership(@params[:membership])
    person.membership.type = get_setting('app_type')
    person.membership.updated_by = @params[:person_id]
    if person.membership.save
    	 flash[:notice] = 'Membership was successfully created.'
    	 redirect_to :controller=> 'person', :action => 'edit', :id => person
    	else
    	 render :action => 'new'
    	end
    end
    For more information about associations and ActiveRecord in general, do take a look at the API documentation, i.e.: http://api.rubyonrails.com/classes/A...s.html#M000473

    For the popup, you could change the link code in the person page to:
    Code:
    <%= link_to image_tag('new'), {:controller => 'memberships', :action => 'new', :person_id => @params[:id]}, :target => '_blank' %>
    Or use an appropiate target window. If you want to use javascript, you could create a helper to automatically create the appropiate code, or just use the JS helper:
    Code:
    <%= link_to_function image_tag('new'), "window.open('#{url_for :controller => 'memberships', :action => 'new', :person_id => @params[:id]}', 'window name', 'window options')" %>
    You could use the X library to ease this task, and also to help you talk to the popup opener window, which I leave to you.

    Further reference:
    http://api.rubyonrails.com/classes/A...r.html#M000432
    http://www.mcli.dist.maricopa.edu/tut/tut27c.html
    http://cross-browser.com/

    Regards,
    Ivan V.
    Last edited by ivanv; Mar 9, 2006 at 08:07. Reason: typo

  5. #5
    SitePoint Zealot ricklach's Avatar
    Join Date
    Nov 2004
    Location
    Victoria BC
    Posts
    116
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ivan,

    I tried your code but I keep getting an error as follows:
    Code:
    Couldn't find Person without an ID
    
    RAILS_ROOT: ./script/../config/..
    
    
    Request
    
    Parameters: {"membership"=>{"person_id"=>"57", "category"=>"Financial Agent", "startdate(1i)"=>"2006", "startdate(2i)"=>"3", "startdate(3i)"=>"9", "enddate(1i)"=>"2006", "enddate(2i)"=>"3", "comment"=>"", "enddate(3i)"=>"9"}, "commit"=>"Save"}
    Of course it is referring to the following line of code:
    Code:
    person = Person.find(@params[:person_id])
    but it just doesn't make sense to me. The person_id is shown in the parameters but it doesn't seem to pick it up. I presumed that I had to add a "hidden" field (or save it in a session variable) to the "New" form to capture the value of person_id so that it was available in the params during membership "create" operation . Is that correct?

    Rick

  6. #6
    SitePoint Zealot
    Join Date
    Feb 2003
    Location
    Mexico City
    Posts
    122
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    That's easy. If you look closely at the parameters, you'll see person_id *under* membership, so either change the hidden input or just use this instead:

    Code:
    person = Person.find(@params[:membership][:person_id])



  7. #7
    SitePoint Zealot ricklach's Avatar
    Join Date
    Nov 2004
    Location
    Victoria BC
    Posts
    116
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ivan,

    Thanks so much for your help. I think I almost have this thing cracked and your guidance has been invaluable. Just one more asthetic question. I want to pass a name to the popup form so I can give the popup preamble a bit of personalization. I have the following code:
    Code:
    <%= link_to_function 'Add New Membership', "window.open('#{url_for :controller => 'memberships', :action => 'new', :person_id => @params[:id], :lastname => @params[:lastname] }', 'membership', 'height=500,width=600,resizable,scrollbars')" %>
    . You will note that I am trying to pass the last name like the person_id. Is this kosher or is there some other methodolgy for passing the variable. How is it displayed in the popup?

    Rick

  8. #8
    SitePoint Zealot
    Join Date
    Feb 2003
    Location
    Mexico City
    Posts
    122
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I don't see any problem with your implementation

    To display it do something like <%= @params[:lastname] %>

    Note that you could also find this information by using the find method of the Person model and then retrieve the lastname, but if you won't need other columns from that model, then your approach is less taxing, and thus better.

  9. #9
    SitePoint Zealot ricklach's Avatar
    Join Date
    Nov 2004
    Location
    Victoria BC
    Posts
    116
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks once again Ivan your input has been invaluable to my learning process. I will close this thread now but I am certain that this will not be the last time I am in the forum.

    Rick


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •