Re: Recent Multi-Blog update Breaks


#1

Piers,

I just wanted to say thank you for all of the work you’ve done on Typo
– including the initial multi-blog support. For my personal blog,
multi-blog support is of no use to me, but I believe that the
refactoring taking place will make Typo faster in the long run (and I
have ideas for other projects where multi-blog support would be
useful).

It seems like there’s been a bit of a backlash on the mailing list
about multiblog support now that its in trunk – hopefully you’ll not
be discouraged, as I believe there are many members of this mailing
list looking forward to multiblog support (looking back through the
number of times its been asked about).

I am curious if you have a roadmap for this feature? Some questions I
had were as follows:

  • How will Typo route to the different blogs? Using subdomain as blog
    key? Modifying routes.rb with special URLs?
  • I like what you’ve done with the Settings/Configuration but
    searching through the set of blogs for one with a particular blog_name
    for example might not be optimal … perhaps the blog_name can be
    promoted to its own field in the blogs table?
  • Will you be adding blog_id to several of the other tables (such as
    blacklist_patterns, categories, contents, resources, sidebars, tags,
    text_filters and users)?
  • Are there pieces of this work that we (I) can help out with?
    Perhaps taking a model/controller and the associated tests to work on?

Thanks again,
Sean


#2

“Sean M.” removed_email_address@domain.invalid writes:

about multiblog support now that its in trunk – hopefully you’ll not
be discouraged, as I believe there are many members of this mailing
list looking forward to multiblog support (looking back through the
number of times its been asked about).

I am curious if you have a roadmap for this feature? Some questions I
had were as follows:

  • How will Typo route to the different blogs? Using subdomain as blog
    key? Modifying routes.rb with special URLs?

Dunno yet, we’ll see what the code tells us. User stories for how
people want to use multiblogs will help us design this. If you have
a need for multiblogs, please bung a ticket in the trac explaining how
you would like to set a new blog up. Just a couple of paragraphs and
maybe a sketch of how you expect the screens to look (html, pdf,
whatever) would be very useful.

  • I like what you’ve done with the Settings/Configuration but
    searching through the set of blogs for one with a particular blog_name
    for example might not be optimal … perhaps the blog_name can be
    promoted to its own field in the blogs table?

Yes, probably. But it’s not an issue until we’re actually handling
multiple blogs, so it can wait. As soon as I write anything that needs
to search on the blog name, you can bet it will get pulled up into the
blogs table proper.

  • Will you be adding blog_id to several of the other tables (such as
    blacklist_patterns, categories, contents, resources, sidebars, tags,
    text_filters and users)?

Yes, there wouldn’t be much point without that, although some of those
will be habtm (or hopefully, by time we come to implement them,
has_many … through) relationships.

  • Are there pieces of this work that we (I) can help out with?
    Perhaps taking a model/controller and the associated tests to work
    on?

I’ve already had a go at doing a spike on adding:

Blog.has_many(:contents)
Blog.has_many(:articles)
Blog.has_many(:comments)
Blog.has_many(:trackbacks)
Blog.has_many(:pages)
Content.belongs_to(:blog)

And it’s a huge change, touching pretty much everything. Even when I
‘cheat’ by overriding perform_action_without_filters (an undocumented,
but very useful ActionController::Base method) to look like:

def perform_action_without_filters
scope_for_content = {:find => {:conditions => “blog_id =
#{this_blog.id}”},
:create => {:blog_id => this_blog.id}}

Content.with_scope(scope_for_content) do
  Article.with_scope(scope_for_content) do
    Comment.with_scope(scope_for_content) do
      Trackback.with_scope(scope_for_content) do
        Page.with_scope(scope_for_content) do
          super
        end
      end
    end
  end
end

there’s still an awful lot of stuff to find and change (it turns out
that ‘new’ doesn’t respect scoping, which is annoying, arguably
correct, and fixable if you’re prepared to mess with overriding
undocumented bits of Rails (which hasn’t stopped us before)).

So, feel free to take it on, but do be aware that there’s rather a lot
to deal with – part of the reason I stopped and applied the patch
when I did was that it was getting awfully big…


#3

On 3/20/06, Piers C. removed_email_address@domain.invalid wrote:>> And it’s a
huge change, touching pretty much everything. Even when I> ‘cheat’ by
overriding perform_action_without_filters (an undocumented,> but very
useful ActionController::Base method) to look like:>> def
perform_action_without_filters> scope_for_content = {:find =>
{:conditions => “blog_id = #{this_blog.id}”},>
:create => {:blog_id => this_blog.id}}>>
Content.with_scope(scope_for_content) do>
Article.with_scope(scope_for_content) do>
Comment.with_scope(scope_for_content) do>
Trackback.with_scope(scope_for_content) do>
Page.with_scope(scope_for_content) do> super>
end> end> end> end> end>> there’s still an
awful lot of stuff to find and change (it turns out> that ‘new’ doesn’t
respect scoping, which is annoying, arguably> correct, and fixable if
you’re prepared to mess with overriding> undo!
cumented bits of Rails (which hasn’t stopped us before)).
Heh. Easy. Since we’re single-threaded, we can just do:
def perform_action_without_filters scope_for_content = {:find =>
{:conditions => “blog_id = #{this_blog.id}”},
:create => {:blog_id => this_blog.id}}
Content.with_scope(scope_for_content) do
Article.with_scope(scope_for_content) do
Comment.with_scope(scope_for_content) do
Trackback.with_scope(scope_for_content) do
Page.with_scope(scope_for_content) do $blog_id =
this_blog.id super end end end
end end
class Content def initialize … self.blog_id =
$blog_id end end
Should work. It’s horrifically ugly, but it should end up working.
I’m not really advocating doing it this way, but it’s probably
theshortest path to working multi-blog support. It’s also the
shortestpath to madness, but we might be able to extract it into
somethingless evil.

Scott


#4

[Wow, that was ugly. I’ve never really tried pasting code into gmail
before. Let’s see if this works]

Heh. Easy. Since we’re single-threaded, we can just do:

def perform_action_without_filters
scope_for_content = {:find => {:conditions => “blog_id =
#{this_blog.id}”},
:create => {:blog_id => this_blog.id}}

Content.with_scope(scope_for_content) do
  Article.with_scope(scope_for_content) do
    Comment.with_scope(scope_for_content) do
      Trackback.with_scope(scope_for_content) do
        Page.with_scope(scope_for_content) do
          $blog_id = this_blog.id
          super
        end
      end
    end
  end
end

class Content
  def initialize
    ...
    self.blog_id = $blog_id
  end
end

Should work. It’s horrifically ugly, but it should end up working.

I’m not really advocating doing it this way, but it’s probably the
shortest path to working multi-blog support. It’s also the shortest
path to madness, but we might be able to extract it into something
less evil.

Scott


#5

“Scott L.” removed_email_address@domain.invalid writes:

Content.with_scope(scope_for_content) do
end

class Content
  def initialize
    ...
    self.blog_id = $blog_id
  end
end

Should work. It’s horrifically ugly, but it should end up working.

If we’re happy with monkeying with undocumented methods, then it’s
better to just avoid the global and do:

class Content
  def initialize(attributes = {})
    attributes.reverse_merge!(scope(:create)) if scoped?(:create)
    super(attributes)
  end
end

I’m not really advocating doing it this way, but it’s probably the
shortest path to working multi-blog support. It’s also the shortest
path to madness, but we might be able to extract it into something
less evil.

See above. I’ll have a crack at doing a spike with this approach
tomorrow (well, later today, after I’ve been asleep for a bit).