Whats the best way to do this?


#1

I have an archive that can have 0 or more extra files associated with
it.

I would like to be able to edit the associated files info on the same
page as the archive info.

Listing the extra files info to the edit form is simple enough, but How
do I form the text input fields for easy (or automatic) pick-up in the
update?

Or am I barking up the wrong tree here?


#2

First, you may want to check

http://www.catb.org/~esr/faqs/smart-questions.html#bespecific

I think you are asking how to display/update a collection of items. When
you
talk about files are you talking about a table that contains information
about files? Do you have a file model (File.rb)? Do you have something
associated with these files, perhaps an archive model (Archive.rb)?

In any case you will likely have a loop in your view to display the 0 or
more files and a loop in your controller to capture the updates.

Please include additional information to get more specific help. Also
you
may want to post code fragments.

-Kelly


#3

Tables are ‘archives’ and ‘extra_files’

Related models:

class Archive < ActiveRecord::Base
belongs_to :category
has_many :extra_file
end

Do model operations work properly for you in script/console?
This should probable be:

   has_many :extra_files

(note the pluralization)

class ExtraFile < ActiveRecord::Base
belongs_to :archive
end

Archive Controller currently looks like this:

class ArchiveController < ApplicationController
scaffold :archive

  def list
          @header = "Test List"
          @subheader = "Everything in the database. Using Adam's

layout"

          #@programs = Archive.find_all
          @program_pages, @programs = paginate :archive
  end

  def edit
          @program = Archive.find(@params["id"])
          @categories = Category.find_all
  end

end

I haven’t used the scaffold function. I’ve always generated the
scaffolds.

I guess you are using the update action that comes with the scaffold
function. This is not likely to work, but I can’t be sure since I
haven’t
done it. It is not likely to work because the scaffold logic does not
handle
relationships to other models. You will need to put your own update
action
in place. In fact, I think you will need to replace all of the scaffold
generated actions with your own versions. You can get a jump start on
this
by using “script/generate scaffold…”

I don’t think there is much point discussing the rest until you get an
update action.

-Kelly


#4

Kelly F. wrote:

Related models:

class Archive < ActiveRecord::Base
belongs_to :category
has_many :extra_file
end

Do model operations work properly for you in script/console?
This should probable be:

   has_many :extra_files

(note the pluralization)

Seems to be working fine. Lists properly in both the list and edit
pages.
Will try changing though…

Changing it caused errors in my listings. Would have to change them too.

> I don't think there is much point discussing the rest until you get an > update action. >

Generated update function:

def update
@archive = Archive.find(params[:id])
if @archive.update_attributes(params[:archive])
flash[:notice] = ‘Archive was successfully updated.’
redirect_to :action => ‘show’, :id => @archive
else
render :action => ‘edit’
end
end


#5

Ok, Sorry about the non specific subject title.

Tables are ‘archives’ and ‘extra_files’

Related models:

class Archive < ActiveRecord::Base
belongs_to :category
has_many :extra_file
end

class ExtraFile < ActiveRecord::Base
belongs_to :archive
end

Archive Controller currently looks like this:

class ArchiveController < ApplicationController
scaffold :archive

def list
	@header = "Test List"
	@subheader = "Everything in the database. Using Adam's layout"
	#@programs = Archive.find_all
	@program_pages, @programs = paginate :archive
end

def edit
	@program = Archive.find(@params["id"])
	@categories = Category.find_all
end

end

Now here is the part(s) where I’m at a loss. Below is the edit.rhtml.
I’ve re-edited the text-input fields so many times, I don’t know what I
haven’t done yet…

Originaly the text-input fields were named by hand, and mostly didn’t
render at all without errors.

You probably don’t need the entire edit.rhtml, but I included it all so
you know about where I started from. The relivent part is near the
bottom, near ‘Extra Files’

Thanks

edit.rhtml

Edit Program Listing

Edit Program Listing

Title

Author

Format

Reference

Release Date

Description
<%= @program.description %>

Misc (extended Description)
<%= @program.misc %>

Baud
<% ['2000','300','2000 BlueRam'].each do |baud| -%> ><%= baud %> <% end -%>

Archival Status

File Location

Extra Ram
Yes /> No />

Category:
<% @categories.each do |category| -%> ><%= category.name %> <% end -%>

Extra Files

<% @program.extra_file.each do |file| -%>
Name: <%= text_field “extra_file”, “name”, “index” => file.id,
“value”=> file.name %>
Location: <%= text_field “extra_file”, “location”, “index” => file.id,
“value”=> file.location %>

<% end -%>

Show | <%= link_to "Back", :action => "list" %>

#6

Seems to be working fine. Lists properly in both the list and edit
pages.
Will try changing though…

Changing it caused errors in my listings. Would have to change them too.

Hmmm. Rails has conventions on names so I surprised this works.
Normally:

  • ModelName.rb will access a database table called model_names.
  • Association collections are pluralized, such as has_many :members
  • Non collection associations are singular, such as belongs_to :group

Of course, changing a model association will break other code. I
surprised
the model works. I’ve been caught a few times with associations defined
backwards, and rails doesn’t help you by throwing an exception - it
simply
fails to work. In other words, I used a belongs_to when I should have
used
has_many, or vice versa.


#7

Now, your view needs to iterate over the associated items. Here is an
example:

Members:
<% for login in ordered_members(@group) %> <%= select_tag('people[]', options_for_select(user_list_for_select(@group), login)) %>
<% end %> <% new_user_select_tag = select_tag('people[]', options_for_select(user_list_for_select(@group))) 5.times do %> <%= new_user_select_tag %>
<% end %>

This is a ui for adding/removing people from a group.

Note the ‘people[]’. These people ids will be delivered to the
controller as
an array.

Here’s the update action:

def update
@group = Group.find(params[:id])
Group.transaction(@group) do
@group.group_members = group_members_from_params(@group)
if @group.errors.empty? and
@group.update_attributes(params[:group])
flash[:notice] = ‘Group was successfully updated.’
redirect_to :action => ‘list’, :id=>@group.period
else
render :action => ‘edit’
end
end
end

Oh, and here’s a related function

def group_members_from_params(group)
group_members = []
unless params[:people].blank?
params[:people].each do |login|
unless login.blank?
gm = (GroupMember.find_by_login_and_period_id(login,
group.period_id) ||
GroupMember.new(:group => group, :login => login))
if gm.group_id != group.id
group.errors.add_to_base(login + ’ is assigned to another
group’)
else
group_members << gm
end
end
end
end
group_members
end

This may be too complicated to use as an example, but I don’t have time
to
make it more succinct.

-Kelly


#8

Kelly F. wrote:

Now, your view needs to iterate over the associated items. Here is an
example:

Unfortunatly, you were right. Too complex for me to pickout the relivent
information, re: my set-up.

Sorry.

As for the extra_file. I wasn’t sure how to name it. It worked that way,
so I left it.

I’m still not sure the input fields on the edit page are named
properly…

Lance


#9

I surprised = I’m surprised

(sometime fingers type what they want)