Weird stuff: validate_uniqueness_of with :scope does not work

Running rails 2.3.8.

I have a two models defined like this

class Member
has_many :folders
before_save: create_default_folders

def create_default_folders!
%w{Inbox Sent}.each do |folder|
unless self.folders.find_by_name(folder)
self.folders.create!(:name => folder, :deletable => false)

class Folder
belongs_to :member

folder names must be unique for each user

validates_uniqueness_of :name, :scope => [:member_id], :allow_blank
=> false,
:case_sensitive => false, :message => ‘already exists for this

------ MembersController
def create
@member =[:member])



So as you can see, what I wish to get when I save a new Member are two
default folders colled (Inbox and Sent).
So I defined the after_save callback. I tested it in script/console
and it works whenever I build and save a Member.

However, as soon as I create a member through a controller-backed
form, the uniqueness validation gets tripped up. I get validation
error from my validates_uniqueness_of as “Folder already exists for
this member”. Which shouldn’t happen.

For some strange reason :scope gets ignored and thus uniqueness check
isn’t properly scoped by member_id…

The weird part is that it all works in script/console, but not via web

Any suggestions???

Thanks in advance!

On Sep 7, 11:55 am, Swartz [email protected] wrote:

Is there some odd interaction because you’re creating these folders
from a before_save (ie the member’s id has not yet been set)?


dont use the before_save use transactions that way it will roll back
actions if there is an error.
and dont use that function you have with the each and all use


it does what you want.

On Tue, Sep 7, 2010 at 7:20 AM, Frederick C.
<[email protected]

That’s what I thought originally about id not being set… but why
does it work from script/console ?
That kind of puzzles me…

On Sep 7, 5:20 am, Frederick C. [email protected]

On Sep 7, 11:55 am, Swartz [email protected] wrote:

Also note that I have to set at least one other folder attribute while
creating a folder ,
so this variant doesn’t help me much.

That code must’ve been 5th iteration of trying to get that call back
to work.

I’ve tried your suggested method.
I’ve so tried create/create!, save/save!.

Everything work from console.
That is I can do
m =
m.x = “value”

It all work beautifully from console. I can test my validation, it

But as soon as I do the same thing (create new Member) from controller
context via form params, the scoped validates_uniqueness_of does not
function as expected.


I’ve created a brand new Rails 2.3.8 app.
No gems, nothing.

I created only the bare necessities:
Two models (Member and Folder)
one controller (MembersController with only new and create actions)
one view (new).

I can create one member with default folders as per my callback (the
very first one), but any subsequent members don’t get default folders
created for them.

But again, when I try the same thing from script/console everything
works (I create new member and, bam, two folders come into existence
as well)…

w t f…

watch this and see if ti helps,

check your attri_accesible, and check if you rae using a gem that uses
attr_protected, it appears you have a problem with mass assignment and
cant see from one controller the attribute that member_id from the
controller i think you need to be able to , also note that with before
there is no member_id in the database to compare the validation with
why i said you should use a transaction and create everything from the
member controller like this

Member.transaction do, blah)!
params[:folder_name].nil? ? name= “Default” : name =
@folder = Folder.find(:conditions =>{:name = name, :member_id=>})

@folder ||= blah)
@folder.member = @member!

try that, the code inside the transaction will rollback if either to the
save fail and everything will go back to the its original state.