class Book; has_many :sections; end
class Section; has_many :documents; end
What I want to do is have a nested button that shows all of the
documents in order belonging to the book.
Something like:
"config.nested.add_link("Documents", [:documents])"
This doesn't work otherwise I wouldn't be posting.
I'm working on something else right now so I thought I would just
throw it to the list to see the best method. The two options I see
are making a helper method to pull these records out, or making a
has_many through association.
What would be the cleanest?
Regards
Mikel
Note that you might need to explicitly specify that Book
has_many :documents, :through => :sections
in order to be ablet o add :documents to the list columns.
If you want a seperate action link in addition to the hyperlink, you
need to set the
:type => :record
property on the link you add.
I haven't got this working yet. What i am after is a link to the
right of each book that allows me to show all nested documents, just
like I have a link called "sections" that allows me to see all nested
sections. Here is the setup:
My models look like this:
class Book
has_many :sections
has_many :documents, :through => :sections
end
class Section
belongs_to :book
has_many :documents
end
class Document
belongs_to :section
delegate :original, :original=, :to => :section
end
In the console, I can do:
>> document.book
=> #<Book:0x3c8e954 @attributes={"updated_at"=>"2007-06-19 22:48:31",
"title"=>"My Book", "revision"=>"May 2007", "id"=>"1",
"created_at"=>"2007-06-18 16:57:41"}>
>> book.documents
=> [#<Document:0x3c84170 @attributes={"job_key"=>nil,
"size"=>"120795", "updated_at"=>"2007-06-19 22:47:02",
"title"=>"Chapter 2", "section_id"=>"1", "imported"=>"1", "id"=>"1",
"progress"=>"100", "saved"=>"1", "position"=>"3",
"file"=>"CHAPTER_2.htm", "created_at"=>"2007-06-18 16:57:59"}>,
#<Document:0x3c84148 @attributes= <<< ETC SNIP >>>
So that works as expected.
Then on the controller side, I have:
class BooksController < ApplicationController
active_scaffold :books do |config|
config.nested.add_link("Sections", [:sections])
config.nested.add_link("Documents", [:documents])
end
end
class DocumentsController < ApplicationController
active_scaffold :document do |config|
config.columns[:book]
end
end
Then I go to the book list view, click on "documents" and I get a
ActiveScaffold::MalformedConstraint in Vms documentsController#table
"Malformed constraint `originals'. If this column is legitimate,
please double-check that it exists in the config.columns set. If not,
and you are using a nested scaffold, please specify or double-check
the reverse association name."
>From what I can tell the associations are correct... at least, that
is what console is telling me.
any ideas?
regards
Mikel
It is only when you try to view it as a nest does it break.
I think I am missing a setting in the documents controller....
regards
Mikel
Lance, the thing that throws me on that though is that in the show and
index views activescaffold correctly shows the contents of the
documents method.... ie it IS finding the association and displaying
correctly (at least the first 50 or so characters) So I see two
options:
1) Is there any way to explicitly give activescaffold a model to list
with said constraints? even if I have to be really careful of what
constraints to apply? :)
2) My only other option is creating my own custom list page I guess
that just iterates through all the documents and shows them...
(1) or (2) what do you think?
Thanks :)
Mikel
Thanks for this, I went away and thought about it all for a bit before
posting another reply...
<heavy middle west accent>
But there is som'thn I just dunna git!
</heavy accent>
I have a model (books) that has many sections, and has many documents
through sections.
If I go to the active scaffold for books, and click on the EDIT tag of
that book, up pops a full edit table and it correctly shows ALL the
documents that belong to the sections belonging to the book. In
otherwords, the has_many through association works 100% through the
Edit view.
Also, if I click show, same deal, voila, all the paragraphs.
Also, if I click the custom nested button that I have made (sections)
I get all the documents as well.
So, me, thinking I am all smart and all, make a custom nested link
like so:
class BooksController < ApplicationController
active_scaffold :books do |config|
config.nested.add_link("Sections", [:sections])
config.nested.add_link("Documents", [:documents])
end
end
I reload the page, see my sparkling new link, click it with all the
hope of generations or ActiveScaffold newbies... and voila!
CRASH
I get the error "Malformed constraint `books'. If this column is
legitimate, please double-check that it exists in the config.columns
set. If not, and you are using a nested scaffold, please... blah".
Should I send it to a controller method first to find all the
documents and then render a different view? Or do I just need to put
something in my model that handles it?
Sorry for the pain in the arse factor... i have a feeling this has
been answered before, a few times... but I can't get my head around
it.
Once I find out how I'll document it for the WIKI! :)
Regards
Mikel
So, then, has this been solved before?
I guess the long term handling would be a config option that says
something like:
config.nested.add_link("SubSubModel", [:subsubmodel], :scope
=> :top_object_id)
or something?
With the models set up as they are now, I can open console and type
this:
>> document = Document.find(:all).first
=> #<Document:0x3b99bfc @attributes={"job_key"=>nil, "size"=>"66667",
"updated_at"=>"2007-06-27 18:51:26", "title"=>"Chapter One",
"section_id"=>"4", "imported"=>"1", "id"=>"33", "progress"=>"100",
"saved"=>"1", "position"=>"1", "file"=>"_01_01_CHAPTER_1.htm",
"created_at"=>"2007-06-27 18:50:44"}>
>> document.book
=> #<Book:0x3b165a4 @attributes={"updated_at"=>"2007-06-27 18:50:06",
"title"=>"Title One", "revision"=>"May 2007", "id"=>"7",
"created_at"=>"2007-06-27 18:50:06"}>
>>
Which is fine, but then I can see the problem when you try and do
something like:
>> documents = Document.find(:all, :conditions => { :book_id => 7 } )
ActiveRecord::StatementInvalid: Mysql::Error: #42S22Unknown column
'documents.book_id' in 'where clause': SELECT *
So then we get smart and add a class method which looks this up by
getting the original_id and looping down through sections pushing the
records into an array to support this and then we get:
>> Document.find_all_by_book_id(7)
=> [[#<Document:0x2d6039c @attributes={"job_key"=>nil,
"size"=>"66667", "updated_at"=>"2007-06-27 18:51:26",
"title"=>"Chapter One", "section_id"=>"4", "imported"=>"1",
"id"=>"33", "progress"=>"100", "saved"=>"1", "position"=>"1",
"file"=>"_01_01_BOOK_1_CHAPTER_1.htm", SNIP ARRAY >>
So wouldn't the trick be... what is the class method that
ActiveScaffold is trying to call on Documents in order to pull up the
association for Books?
That is something I haven't figured out yet... I am going to dive into
the code and find out... but this can't be too hard to fix I am
sure.............?
Or am I dreaming? :)
Regards
Mikel
Actually... works better than that. more like 120%!
On a has_many => through belongs_to one... you don't even have to
specify the book id!
You also don't have to do ANY CONFIGURATION in the controllers!
I just sandboxed this with the following code:
class Book < ActiveRecord::Base
has_many :sections
has_many :documents, :through => :sections
end
(title:string)
class Section < ActiveRecord::Base
has_many :documents
belongs_to :book
end
(title:string book_id:integer)
class Document < ActiveRecord::Base
belongs_to :section
end
(title:string section_id:integer text:text)
Then all the controllers just have "active_scaffold".. nothing else
That gives you the documents as a subset of books... click it and you
get a nice beautiful menu of all the documents!
WOOOOOHOOOOO!!!!!!
Lance, you rock :) I'll play with it some more and see if I can break
it and even maybe possibly fix it :)
Regards
Mikel