Accessing request from model (or observer)


#1

Hello,

I am currently developing an engine which allows several different
sites to be served using the same code. The implementation is like
this:

  • every Post has a site_id field, which is set to the ID is the site
    to which the post belongs to.
  • in Apache config, I have something like:
    ServerName site1.com
    ServerAlias site2.com

site1.com and site2.com are different sites, with ID’s 1 and 2. When a
user accesses the site, engine detects which url is used (by comparing
request.host against sites database) and serves only posts with the
corresponding site_id. @current_site variable is set on application
controller level before any page is served to user.

The question:
I want to make the process of creating posts as clean as possible.
Meaning that when a post is saved, site_id is automatically attached
to it. The best possible way would be to do it in post model’s
before_save function, but the problem is that neither @current_site
variable, nor request is available to the post model.
I tried to use observers with no luck (same access problems as with
model)

Any ideas or may be some fresh approaches are very appreciated. I
really would like to leave setting site_id in controller as a last
resort (doesn’t take much time to implement, but just oh so un-
clean :slight_smile:

TIA,
Mike.


#2

Just set the site_id in the controller before calling post.save.

b


#3

Thanks for the great idea Ben!

That’s how I have implemented it (is it the way you meant it?). All
controllers in admin interface have AdminController as a parent so I
define the “fix” on the topmost level.

class AdminController < ApplicationController

before_filter :set_site_id, :only => [:create, :update]

private
def set_site_id()
params[:page][:site_id] = @current_site.id
end

I wonder if there’s a better way? Or the current approach is good
enough. I don’t really like to juggle with params array manually.

mike.


#4

Looks like the approach above solves the problem with setting site_id
on save, but it doesn’t solve the problem overall.

I do need some way to access either @params or a variable set inside
the action controller. That’s because I want to modify model’s default
find method so all search would return only records which belong to
current site.

Currently I have the following find method which overrides the default
find in the model:

def self.find(*args)
with_scope(:find => { :conditions => “posts.post_type=‘page’” })
do
super
end
end

What I would like to be able to do it:

def self.find(*args)
with_scope(:find => { :conditions => [“posts.post_type=‘page’ and
posts.site_id=?”, @current_site_id] }) do
super
end
end

Where @current_site_id is defined in action controller (that’s where
the @request array becomes available).
Any ideas?


#5

Mikhail Kornienko wrote:

 with_scope(:find => { :conditions => ["posts.post_type='page' and

posts.site_id=?", @current_site_id] }) do
super
end
end

Where @current_site_id is defined in action controller (that’s where
the @request array becomes available).
Any ideas?

Well, find has *args to play with… maybe just pass the current_site_id
to find. Don’t know if having an extra arg in the array will make the
call to super puke, but you can always remove it before calling super.

b