Forum: Ruby on Rails Problems with multiple ActiveRecords and Validations

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
624d70886668145f095437ea3f051b42?d=identicon&s=25 Dominik (Guest)
on 2006-04-10 21:20
Hi all,

I am a RoR newbie and have the following scenario set up:

There are 2 ActiveRecords involved, the first one being "User", the
second one being "Visibility".

The corresponding users table holds address informations regarding a
User. The visibilities table holds visibility settings for the
individual columns of the users table (i.e. firstname, lastname, country
should be visible to everybody while the credit card data should be only
visible to the admin, and so on) for individual users. It has
practically the same schema as the users table and a foreign key, namely
user_id. The relationship between the tables is 1:1.

Now I have created an "edit user profile" view which displays all the
individual form elements corresponding to the columns of the user table.
Next to each form element is a checkbox which is populated from the
visibilities-table. (Un-)checking the checkbox you can decide which
elements should be visible in the "show user profile" view. I hope you
can follow me so far.

Everything is handled from a UserController which extracts the
visibility alongside the user and prepares everything for display.

Problems arise, if the ActiveRecord validations come into play (e.g.
there is a validates_presence_of :lastname rule). If everything
validates successfully, the update action is invoked and all changes are
saved (in the users and visibilities tables). But if a validation fails
and the edit user profile view is rendered once again ONLY the submitted
values of the User ActiveRecord are filled into the form fields once
again. But all the checkboxes are unchecked!

I haven't been able to figure out what exactly does happen in case a
validation fails, although I have screened the source code of the
ActiveRecord and ActiveView classes and come across the magic errors
object.


Here some source code:

users_controller.rb:

def edit
  @user = User.find(params[:id])
  @visibility = @user.visibility
end

user.rb
class User < ActiveRecord::Base
  validates_presence_of :lastname, :firstname
  has_one :visibility
end

edit.rhtml (excerpt)
<%= text_field 'user', 'lastname'  %>
<%= check_box 'visibility', 'lastname', {}, "public", "admin" %> </p>


I am desperately trying to make that work. Any ideas?

Best regards,
 Dominik
59ea1b450935b9d70abfec4186b7a4d5?d=identicon&s=25 Jeff Coleman (progressions)
on 2006-04-10 22:09
Dominik wrote:

> users_controller.rb:
>
> def edit
>   @user = User.find(params[:id])
>   @visibility = @user.visibility
> end
>
> user.rb
> class User < ActiveRecord::Base
>   validates_presence_of :lastname, :firstname
>   has_one :visibility
> end
>
> edit.rhtml (excerpt)
> <%= text_field 'user', 'lastname'  %>
> <%= check_box 'visibility', 'lastname', {}, "public", "admin" %> </p>
>
>
> I am desperately trying to make that work. Any ideas?
>
> Best regards,
>  Dominik

You might want to post your "update" action from users_controller, too.
It's hard to tell what happens exactly without that.

Jeff Coleman
624d70886668145f095437ea3f051b42?d=identicon&s=25 Dominik (Guest)
on 2006-04-10 22:41
Jeff Coleman wrote:
> Dominik wrote:
>
>> users_controller.rb:
>>
>> def edit
>>   @user = User.find(params[:id])
>>   @visibility = @user.visibility
>> end
>>
>> user.rb
>> class User < ActiveRecord::Base
>>   validates_presence_of :lastname, :firstname
>>   has_one :visibility
>> end
>>
>> edit.rhtml (excerpt)
>> <%= text_field 'user', 'lastname'  %>
>> <%= check_box 'visibility', 'lastname', {}, "public", "admin" %> </p>
>
> You might want to post your "update" action from users_controller, too.
> It's hard to tell what happens exactly without that.


Here you are:

def update
  @user = User.find(params[:id])
  @user.create_visibility(params[:visibility]) unless @user.visibility
  @visibility = @user.visibility
  if @user.update_attributes(params[:user]) &&
@user.visibility.update_attributes(params[:visibility]) then
    flash[:notice] = 'Update was successful.'
    redirect_to :action => 'show', :id => @user
  else
    render :action => 'edit'
  end
end

And here is the relevant form-tag from the view, but that is quite
obvious:
<%= start_form_tag :action => 'update', :id => @user %>

Thanks in advance!

Dominik
624d70886668145f095437ea3f051b42?d=identicon&s=25 Dominik (Guest)
on 2006-04-11 08:49
Hi all,

I just wanted to tell you how delighted I am now: I have found the bug
after one night's sleep - stupid me!

It had nothing to do with the edit or update action (which I posted
above) but with the new/create actions: the line @visibility =
@user.visibility was missing and consequently the new action could not
fill in the checkboxes after a failed update from the instance variable
@visibility.

For all the newbies in the world I just want to explicitly state that
the validations take place while update_attributes is running. If any
validations fail update_attributes returns false and you can control
what happens next with a call to render :action or redirect to :action.


Rails rocks!
This topic is locked and can not be replied to.