Forum: Ruby on Rails master detail problem

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Rube G. (Guest)
on 2006-01-12 17:52
Hello all,

Has anyone done one of these? I've done similar things in java and php,
by having easy access to SQL statements. I am new to Ruby/Rails( I've
been at it for 10 days ) and thus far find it extremely confusing. I've
got a bit more of a handle on it from the Agile book that someone loaned
me, but I still find it hard to understand.

Anyway, I've got two tables with a one to many between them. I am able
to have a page display the parent table and its asscociated fields for
CRUD, but I am baffled at how to get at the child table for updating and
creating. Here is where I am at:

When you go to the edit page for the parent table, I've placed a link
that brings you to a new page with this:

<h1>Editing Module Unit ID: <%= @moduleunit.id %> Links</h1>

<%= start_form_tag :action => 'updatelinks', :id => @moduleunit %>
  <%= render :partial => 'linkform' %>
  <%= submit_tag 'Edit Links Entry' %>
<%= end_form_tag %>

<%= link_to 'Show', :action => 'show', :id => @moduleunit %> |
<%= link_to 'Back', :action => 'list' %>

where moduleunit is the primamry key of the parent table. This loads the
linkform partial( is that correct? ) which contains this:

<% for modulelink in @moduleunit.modulelinks %>
<tr><td class="altcolor">Link Anchor</td><td><input type="text"
name="modulelink[linkAnchor<%= modulelink.id %>]" value="<%=
modulelink.linkAnchor%>"/></td></tr>
<tr><td class="altcolor">Link Code</td><td><input type="text"
name="modulelink[linkCode<%= modulelink.id %>]" value="<%=
modulelink.linkCode%>"/></td></tr>
<tr><td class="altcolor">Link Target</td><td><input type="text"
name="modulelink[linkTarget<%= modulelink.id %>]" value="<%=
modulelink.linkTarget%>"/></td></tr>
<tr><td colspan="3">&nbsp;</td></tr>
<% end %>

I've appended the child primamry key because there may be more than one
and I saw no facility in rails to handle this.

At this point, I am trying to make a method in the parent controller
called updatelinks but cannot get things working with .find or
params[:id] or anything else.

Is there a way I can just use plain SQL here? I know it is not the rails
way, but I just need to get this working and I have spent too long
trying it through rails syntax, getting more confused, etc. There must
be an easier way through straight SQL, yes?

Thanks and sorry for being so clueless. I just can't "get" rails :-(
Rube G. (Guest)
on 2006-01-12 23:49
Rube G. wrote:
>
> Hello all,
>
> Has anyone done one of these? I've done similar things in java and php,
> by having easy access to SQL statements. I am new to Ruby/Rails( I've
> been at it for 10 days ) and thus far find it extremely confusing. I've
> got a bit more of a handle on it from the Agile book that someone loaned
> me, but I still find it hard to understand.
>
> Anyway, I've got two tables with a one to many between them. I am able
> to have a page display the parent table and its asscociated fields for
> CRUD, but I am baffled at how to get at the child table for updating and
> creating. Here is where I am at:
>
> When you go to the edit page for the parent table, I've placed a link
> that brings you to a new page with this:
>
> <h1>Editing Module Unit ID: <%= @moduleunit.id %> Links</h1>
>
> <%= start_form_tag :action => 'updatelinks', :id => @moduleunit %>
>   <%= render :partial => 'linkform' %>
>   <%= submit_tag 'Edit Links Entry' %>
> <%= end_form_tag %>
>
> <%= link_to 'Show', :action => 'show', :id => @moduleunit %> |
> <%= link_to 'Back', :action => 'list' %>
>
> where moduleunit is the primamry key of the parent table. This loads the
> linkform partial( is that correct? ) which contains this:
>
> <% for modulelink in @moduleunit.modulelinks %>
> <tr><td class="altcolor">Link Anchor</td><td><input type="text"
> name="modulelink[linkAnchor<%= modulelink.id %>]" value="<%=
> modulelink.linkAnchor%>"/></td></tr>
> <tr><td class="altcolor">Link Code</td><td><input type="text"
> name="modulelink[linkCode<%= modulelink.id %>]" value="<%=
> modulelink.linkCode%>"/></td></tr>
> <tr><td class="altcolor">Link Target</td><td><input type="text"
> name="modulelink[linkTarget<%= modulelink.id %>]" value="<%=
> modulelink.linkTarget%>"/></td></tr>
> <tr><td colspan="3">&nbsp;</td></tr>
> <% end %>
>
> I've appended the child primamry key because there may be more than one
> and I saw no facility in rails to handle this.
>
> At this point, I am trying to make a method in the parent controller
> called updatelinks but cannot get things working with .find or
> params[:id] or anything else.
>
> Is there a way I can just use plain SQL here? I know it is not the rails
> way, but I just need to get this working and I have spent too long
> trying it through rails syntax, getting more confused, etc. There must
> be an easier way through straight SQL, yes?
>
> Thanks and sorry for being so clueless. I just can't "get" rails :-(

After fruitless searching and trying to get this working, I've shelved
using rails in favor of PHP. I could get a master/detail going for the
Show view but I can't understand how to link the child back to the
parent for updates or creating.

If someone could make a HOWTO for this common need ( master/detail )
that'd probably help a lot of people. For me, it just seems to
abstracted to do with rails ( not saying it can't be done! ). I find
PHP to be much clearer, as I can easily get my hands on the GET/POST
data and write the SQL.
Heikki Ylönen (Guest)
on 2006-01-13 13:49
I think you would get answers if you described the problem with less
words.
For me that's just too much text to read. Just forget id's and sql and
use human language. :)
JLM (Guest)
on 2006-01-13 14:04
Personally get instant rails it has two app preinstalled you can pick
at, and then get some webspace that allows you to auto generate typo and
tracks from cpannel or something ie railplayground or others. Since once
you get something up and have read a bit of the theory you begin to
realise this is v.powerfull!  I look at ruby code and can sort of almost
follow it I look at php and think what a mess!

I did try the standard ruby but I had problems with paths so Instant
rails solved that and made it possible for me to setup easy at the end
of the day I don't mind code I just hate messing with operating systems
and settings.
Rube G. (Guest)
on 2006-01-13 18:25
JLM wrote:
> Personally get instant rails it has two app preinstalled you can pick
> at, and then get some webspace that allows you to auto generate typo and
> tracks from cpannel or something ie railplayground or others. Since once
> you get something up and have read a bit of the theory you begin to
> realise this is v.powerfull!  I look at ruby code and can sort of almost
> follow it I look at php and think what a mess!
>
> I did try the standard ruby but I had problems with paths so Instant
> rails solved that and made it possible for me to setup easy at the end
> of the day I don't mind code I just hate messing with operating systems
> and settings.

Hi JLM,

Thanks for the reply. I also chose Instant Rails because I did not want
to install  all the extra stuff ruby needed, just to give it a try.
Instant Rails is nice.

I've looked at the sample applications, as well as the Depot app in the
Agile book. None of them seems to deal clearly with multi-table
relationships. I don't know... I just can't seem to grasp Ruby/Rails
abstraction. Clear as mud. Java and PHP are so much easier and clearer
to me! $POST or request object from a form is simple array of strings,
make your SQL ( or better, use Hibernate ), and go.

Heikki, I don't understand? I tried to describe my problem simply, and
provide some code for context. Was that too much? And if you are saying
Ruby/Rails is human language...!!! It is so hard to read! SQL is plain
and easy! id's make sense! Automagic association is not good when
something breaks. You have nothing to look at to understand error.

Well, thank you all. Rails is just too strange to me. I already solve my
problem in one afternoon with php, where I spent a week in rails just
being sad :-(

Good luck!
Nic W. (Guest)
on 2006-01-13 19:35
(Received via mailing list)
'Rube',

  Have you tried to do this, or are you just reading and unable to see
how it would play out? I suggest playing around with the code, and
then watching your DEVELOPMENT.LOG and its subsequent queries.

There is space dedicated in the Agile book about child saving, and
which direction associations will be saved, there is even a side-bar
about it.

Then again, if Java and PHP are easier for you.......I don't know what
to say.

- Nic.

On 1/13/06, Rube G. <removed_email_address@domain.invalid> wrote:
> > of the day I don't mind code I just hate messing with operating systems
> relationships. I don't know... I just can't seem to grasp Ruby/Rails
> Well, thank you all. Rails is just too strange to me. I already solve my
> http://lists.rubyonrails.org/mailman/listinfo/rails
>


--
- Nic
James L. (Guest)
on 2006-01-13 19:44
(Received via mailing list)
On 1/13/06, Rube G. <removed_email_address@domain.invalid> wrote:
> Heikki, I don't understand? I tried to describe my problem simply, and
> provide some code for context. Was that too much? And if you are saying
> Ruby/Rails is human language...!!! It is so hard to read! SQL is plain
> and easy! id's make sense! Automagic association is not good when
> something breaks. You have nothing to look at to understand error.

I read your original post twice, and I still have no idea what your
question was.  If you solved it in PHP, then great.  When you're on a
tight timeline, learning a new language isn't always the best idea
anyway.

-- James
Rube G. (Guest)
on 2006-01-13 20:56
James L. wrote:
> On 1/13/06, Rube G. <removed_email_address@domain.invalid> wrote:
>> Heikki, I don't understand? I tried to describe my problem simply, and
>> provide some code for context. Was that too much? And if you are saying
>> Ruby/Rails is human language...!!! It is so hard to read! SQL is plain
>> and easy! id's make sense! Automagic association is not good when
>> something breaks. You have nothing to look at to understand error.
>
> I read your original post twice, and I still have no idea what your
> question was.  If you solved it in PHP, then great.  When you're on a
> tight timeline, learning a new language isn't always the best idea
> anyway.
>
> -- James

My apologies. I guess it wasn't that clear. You know what a
master/detail relationship is, yes? Here was the issue.

Parent table called X has one to many relation to Child table Y

Call up a view to display ONE record from X and 1-N records from Y

This worked fine. This told me the relationship I defined in the two
models was working.

Now I need to allow someone to edit rows from Y.

On edit page, I get ONE record from X to load, but cannot get Y to work.

I decided to break it out. You call up record for X. Now you have the
primary key id for X whcih is foreign key in Y for each related row,
yes?

So, I pass that to another page that should load just the Y table. This
worked.

Now, if I edited a field and try to save it back... BOOM! Can't do this!

Why? Well, first, I could not see how to name my form elements in such a
way that :params would see them as belonging to the parent table X.

def updatelinks
    # how do we get the X ID
    # and all the Y link groups?
    # how does the form work with :params??
    @parenttable = Parenttable.find(params[:id])
    @parenttable.childtable = ???? # tried many things here! Nothing
works!
    if @moduleunit.update_attributes(params[:moduleunit])
      flash[:notice] = 'Parenttable was successfully updated.'
      redirect_to :action => 'show', :id => @parenttable
    else
      render :action => 'editlinks'
    end
end


If I can't explain this clearer, then it would seem to support my
argument that rails is a difficult thing to program with. It seems so
simple and yet, I see many people asking about table relations with
great confusion. The Agile book did not help me, either. I don't see
clear explanation of things in Depot example, just "accept that this
does something". That's ok, but I need more.

Please don't think I am saying "rails sucks" or something. I tried hard
to use it, gave it a fair shake, and it just isn't a good solution for
me. Too much odd syntax and abstraction in an unclear manner, in my
opinion, of course.

Thank you.
Nic W. (Guest)
on 2006-01-13 21:43
(Received via mailing list)
Someone can chime in with a more concise way, but have you tried doing
this:

NOTE: Not all of this code is correct, I'm just typing it out quickly

In your controller, under 'edit', do a find on the y_table where the
foreign key is equal to the X key.

something like:
@y_bits =  y.find(:all, :conditions => "x_id = :id ", :order =>
"created_on DESC")

Now, in your view, loop over @y_bits, and create a link_to to
edit/show/delete the pieces of "y that belong to x"

Okay, you don't want to do a link_to, you want to edit Y_bits in that
page right?

Well, those are going to get passed right back to your controller,
under Update. Look at the source of your EDIT page and see what params
are created in HTML for the Y_bits. This is a quick way of knowing how
your Y_bits are being passed back.....

Now, in your update controller for X, take those incoming Y_bits, and
update their Y_table. The code will look similiar to the code for the
X update.

Let me know if you want more detail, I'm just giving you a big
picture, or if anybody else can jump in and fix my work :)

- Nic.

On 1/13/06, Rube G. <removed_email_address@domain.invalid> wrote:
> > tight timeline, learning a new language isn't always the best idea
>
>
>     # and all the Y link groups?
> end
> to use it, gave it a fair shake, and it just isn't a good solution for
> http://lists.rubyonrails.org/mailman/listinfo/rails
>


--
- Nic
Jules J. (Guest)
on 2006-01-13 22:24
I'm not sure if this is what you want:

Say parenttable = posts and childtable = comments, ok?

You have two controllers: PostsController and CommentsController. If you
go to:
http://yourapp/posts/show/2

You'll see some information about the post AND you'll see a list of
comments. You want to update one of the comments. Then you create links
to the edit page of CommentsController:

<% for comment in @post.comments %>
<h2><%=h comment.title %></h2>
<%=h comment.text %>
<%= link_to 'Edit this comment',
  :controller => 'comments',
  :action => 'edit',
  :id => comment # !!!!!!!!!! This tells Rails that we are updating THIS
comment, and not another comment. It will generate a link like:
http://yourapp/comments/edit/5
%>
<% end %>

And you probably want to redirect back to the post if you update the
comment, so in your:

class CommentsController < ApplicationController
  #...
  def edit
  #...
  redirect_to :controller => 'posts', :action => 'show', :id => @comment
  end
end

And you're done.

If this is not what you want, please tell me how the page looks to the
user, so:

"on page yourapp/posts/edit the user needs to see ..."

That is easier to understand.
Rube G. (Guest)
on 2006-01-13 22:41
I hope this formats correctly. I will try to put my comments in repsonse
to yours, with rube: in front.

Nic W. wrote:
> Someone can chime in with a more concise way, but have you tried doing
> this:
>
> NOTE: Not all of this code is correct, I'm just typing it out quickly
>
> In your controller, under 'edit', do a find on the y_table where the
> foreign key is equal to the X key.
>
> something like:
> @y_bits =  y.find(:all, :conditions => "x_id = :id ", :order =>
> "created_on DESC")

rube: this works, but not quite right. no matter how I try and refer to
x_id, rails makes it the foreign key of the Y table, which of course, is
wrong. I cannot use @x.id or the class name itself, X.id either. How do
I get the correct instance variable of the current x object's id in
there?

>
> Now, in your view, loop over @y_bits, and create a link_to to
> edit/show/delete the pieces of "y that belong to x"

rube: I do not understand this. I was able to make a loop ( that's how I
saw that the incorrect data was returned, but how do I make a link_to
that passes a group of ids?

>
> Okay, you don't want to do a link_to, you want to edit Y_bits in that
> page right?
>
> Well, those are going to get passed right back to your controller,
> under Update. Look at the source of your EDIT page and see what params
> are created in HTML for the Y_bits. This is a quick way of knowing how
> your Y_bits are being passed back.....

rube: i guess this follows the link_to problem. Even if I knew what you
meant or passed the ids ( remember, there could be 1-N ), I still don't
see where the form fields get created. Did you mean link to edit page
created for Y by rails generate?

I tried copying the form code from there and using it in the parent edit
page, but then a) the fields come out empty when they should have
editable data and b) it will fail to handle multiple records from Y.

>
> Now, in your update controller for X, take those incoming Y_bits, and
> update their Y_table. The code will look similiar to the code for the
> X update.

rube: can't get there :-(

>
> Let me know if you want more detail, I'm just giving you a big
> picture, or if anybody else can jump in and fix my work :)
>
> - Nic.

Maybe this forum is a poor communication medium for such a problem to be
described for rails? Or I describe it poorly too!

I would say look up about master/detail editing and updating. I would
like to see someone do this in rails, if only to show it can handle such
a thing. Better, it would help many people trying this in rails, I am
sure.
Jules J. (Guest)
on 2006-01-13 22:57
Could you tell me:

1. What your database schema is
2. What your model is (X has_many :ys, etc)
3. What you want the user to edit?
3.1 Do you want the user to edit the master associated too. So you have
a posts with comments. You edit one comment, do you want to be able to
select a post for it. In other words, move the comment to another post?

Thanks,

Jules
Rube G. (Guest)
on 2006-01-13 23:17
Jules J. wrote:
> Could you tell me:
>
> 1. What your database schema is

CREATE TABLE links (
  `id` int(4) NOT NULL auto_increment,
  `item_id` int(6) NOT NULL default '0',
  `linktext` varchar(50) NOT NULL default '',
  `linkmeta` varchar(50) NOT NULL default '',
  `linkurl` varchar(250) NOT NULL default '',
  PRIMARY KEY  (`id`)
)

CREATE TABLE `items` (
  `id` int(6) unsigned NOT NULL auto_increment,
  `description` longtext NOT NULL
  PRIMARY KEY  (`id`)
)

I've simplified it down to the basic stuff.

> 2. What your model is (X has_many :ys, etc)

items has_many :links
links belongs_to :item

> 3. What you want the user to edit?

user should be able to edit fields in both the parent table and the
child table

> 3.1 Do you want the user to edit the master associated too. So you have
> a posts with comments. You edit one comment, do you want to be able to
> select a post for it. In other words, move the comment to another post?
>
> Thanks,
>
> Jules

Ultimate goal:

user should be able to edit fields in both the parent table and the
child table. Ideally this would happen on the same page, but going to
another for child table is ok.

user should be able to do one of three actions on child table.

1. edit existing data ( text field populates with data on page load )
2. remove a row, whether there is only one or N
3. add a row, whether there is none or N
Heikki Ylönen (Guest)
on 2006-01-13 23:18
Jules J. wrote:
> 1. What your database schema is
> 2. What your model is (X has_many :ys, etc)
> 3. What you want the user to edit?
> 3.1 Do you want the user to edit the master associated too. So you have
> a posts with comments. You edit one comment, do you want to be able to
> select a post for it. In other words, move the comment to another post?

3 & 3.1 : What do you see on each page and what do you expect to happen?
Heikki Ylönen (Guest)
on 2006-01-13 23:32
Rube G. wrote:
> Ultimate goal:
>
> user should be able to edit fields in both the parent table and the
> child table. Ideally this would happen on the same page, but going to
> another for child table is ok.
>
> user should be able to do one of three actions on child table.
>
> 1. edit existing data ( text field populates with data on page load )
> 2. remove a row, whether there is only one or N
> 3. add a row, whether there is none or N

Edit page:
- item data
- all current item's links

You can edit them all and on submit the item and it's links will be
saved to the database? (I might have had similar problem earlier)
Jules J. (Guest)
on 2006-01-13 23:34
Everything you want is described here:

http://manuals.rubyonrails.com/read/chapter/48

Please post here if you have any problems!

Jules
Rube G. (Guest)
on 2006-01-14 00:16
Jules J. wrote:
> Everything you want is described here:
>
> http://manuals.rubyonrails.com/read/chapter/48
>
> Please post here if you have any problems!
>
> Jules

Thank you, Jules. I will try this over the weekend. Odd that I searched
and searched on google and these pages never came up. Also, I must have
missed them on the rails site while looking for help. Hopefully I'll
have better luck with this than the book presented.
This topic is locked and can not be replied to.