Belongs_to

hi i have a belongs to set up between 2 models. Exhibition belongs to
license_instance. The model code is fine because i use it in a number of
other places on the site. One thing i would like to do is create the 2
models at the same time in one form. I have been using
http://railsforum.com/viewtopic.php?id=717 but i am running in to
trouble when i try and save.

The folloing is my controller code

#####################################################
def create
#create the new @exhibition model
@exhibition = Exhibition.new(params[:details])
@exhibition.user = current_user
@exhibition.listing_status = ListingStatus.find_by_id(2)
@exhibition.image_id = -1

#check if license needs to be created for this model.
if @exhibition.description != ""
  @licenseinstance =

@exhibition.build_license_instance(params[:newdetails])
@licenseinstance.format = “Text”
@licenseinstance.license_jurisdiction_id = 1
end

#checks if the is free button has been ticked. if so sets this to

the price.
if params[:otherdetails][:isfree] == “yes”
@exhibition.admission_price = “Free”
end

#saves the whole exhibition with the license details included.
if @exhibition.save
  flash[:notice] = "Exhibition details inserted"
  session[:exhibition] = @exhibition
  redirect_to :controller => "/listing/edit", :action => "index"
else
  flash[:notice] = "Error inserting Exhibition and creating license"
  @license_types = LicenseType.find(:all)
end

end
#####################################################

everything works but the license instance does not get saved. What am i
doing wrong??? Do i have to call the .save method on the license object?
I was under the understanding that the .build_license_instance method
would do this when the .save method on the exhibition is called.

Thanks for taking time reading this post.

On Dec 20, 7:18 pm, Stewart [email protected] wrote:

#create the new @exhibition model
  @licenseinstance.license_jurisdiction_id = 1
  flash[:notice] = "Exhibition details inserted"

doing wrong??? Do i have to call the .save method on the license object?
I was under the understanding that the .build_license_instance method
would do this when the .save method on the exhibition is called.

Where does the license_instance actually get connected with the
exhibition? What exactly is in the build_license_instance method?

Best,

-r

Thanks for taking time reading this post.


Posted viahttp://www.ruby-forum.com/.


Ryan R.
http://raaum.org
http://rails.raaum.org – Rails docs
http://locomotive.raaum.org – Self contained Rails for Mac OS X

[email protected] wrote:

On Dec 20, 7:18 pm, Stewart [email protected] wrote:

#create the new @exhibition model
  @licenseinstance.license_jurisdiction_id = 1
  flash[:notice] = "Exhibition details inserted"

doing wrong??? Do i have to call the .save method on the license object?
I was under the understanding that the .build_license_instance method
would do this when the .save method on the exhibition is called.

Where does the license_instance actually get connected with the
exhibition? What exactly is in the build_license_instance method?

Best,

-r

the build_license_instance method i thoght was something that you got
from active record when you implemented a belongs_to.

hi,

try
@licenseinstance =License.new(params[:newdetails])#perhaps this is
the
case for you
@exhibition.liscense_instance=@licenseinstance
then save
analogous to above code worked for me

regards
gaurav

gaurav bagga wrote:

hi,

try
@licenseinstance =License.new(params[:newdetails])#perhaps this is
the
case for you
@exhibition.liscense_instance=@licenseinstance
then save
analogous to above code worked for me

regards
gaurav

the save works great! However it just seems to ignore the validation for
the license_instance. I need the whole action to fail if details of the
license_instance are invalid.

[email protected] wrote:

On Dec 20, 7:18 pm, Stewart [email protected] wrote:

#create the new @exhibition model
  @licenseinstance.license_jurisdiction_id = 1
  flash[:notice] = "Exhibition details inserted"

doing wrong??? Do i have to call the .save method on the license object?
I was under the understanding that the .build_license_instance method
would do this when the .save method on the exhibition is called.

Where does the license_instance actually get connected with the
exhibition? What exactly is in the build_license_instance method?

Best,

-r

Thanks for taking time reading this post.


Posted viahttp://www.ruby-forum.com/.


Ryan R.
http://raaum.org
http://rails.raaum.org – Rails docs
http://locomotive.raaum.org – Self contained Rails for Mac OS X

In this part of the code

#check if license needs to be created for this model.
if @exhibition.description != ""
  @licenseinstance = 

@exhibition.build_license_instance(params[:newdetails])
@licenseinstance.format = “Text”
@licenseinstance.license_jurisdiction_id = 1
end

Have a go at:

@licenseinstance =License.new(params[:newdetails])

if @licenseinstance.valid?
    @exhibition.license_instance=@licenseinstance
else
  flash[:notice] = "License is not valid"
  redirect_to :action =>"somewhere" and return
end

if @exhibition.save
  flash[:notice] = "Saved!"
  redirect_to :action =>"somewhere" and return
end

You might want to look at transactions
(ActiveRecord::Transactions::ClassMethods).
and validates_associated
(ActiveRecord::Validations::ClassMethods)

askegg wrote:

Have a go at:

@licenseinstance =License.new(params[:newdetails])

if @licenseinstance.valid?
    @exhibition.license_instance=@licenseinstance
else
  flash[:notice] = "License is not valid"
  redirect_to :action =>"somewhere" and return
end

if @exhibition.save
  flash[:notice] = "Saved!"
  redirect_to :action =>"somewhere" and return
end

You might want to look at transactions
(http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html#M000585).
and validates_associated
(ActiveRecord::Validations::ClassMethods)

once again the image save works however the license does not get created
unless i call the save methond more than once and I really need to avoid
doing this.

This is the way Rails works.

belongs_to is not considered an “owning” type assosiation. Only the
has_one & has_many will propagate save & delete to their child objects.

I also consider this a problem with Rails because there are many
types of entity relationship where it is natural for the “owning”
entity to have the foreign key, for example with an Address entity,
where you want other entities to be able to use the Address entity
(or even for one entity to have several addresses, but each is a
separate to-one relationship, ie: business_address, billing_address,
etc.)

Other ORMS I’ve used in the past have had the opposite restriction,
where you ONLY had the ability to create a has_one association on the
object that had the foreign key, and had to emulate other-object-
foreign-key associations using has_many with code to restrict
membership to 1.

In my opinion an ORM should be agnostic about which side of a to-one
association is considered parent and which is considered child.

Here is some more discussion of this issue:

http://javathehutt.blogspot.com/2006/05/rails-realities-part-12-
active-record.html
http://grahamglass.blogs.com/main/2005/11/my_ruby_on_rail_3.html

This has been discussed many times, and the solution is to use
polymorphic associations. Although polymorphic associations are very
useful, to my mind they are not the best way of modelling simple
to_one relationships where the parent record holds the foreign key.
And, as the javathehutt guy mentions, if you use polymorphic
associations, you are going to need custom code to propagate saves
anyway except when model objects are first created.

Since it has been discussed many times, it seems unlikely that this
aspect of Rails will change.

Also, see http://javathehutt.blogspot.com/2006/07/rails-realities-
part-14-rtfm-and-dont.html for a potential gotcha with propagating
deletions.

Cheers,
Michael J.

hi,

I customized my errors method this way
and made it helper and had
validates_associated :model_name#whatever model in my model code

def errors_finder(object_name, options = {})
options = options.symbolize_keys
object = instance_variable_get("@#{object_name}")
if object && !object.errors.empty?
content_tag(“div”,
content_tag(
options[:header_tag] || “h2”,
“#{pluralize(object.errors.count, “error”)} prohibited
this
#{object_name.to_s.gsub(”_", " “)} from being saved”
) +
content_tag(“p”, “There were problems with the following
fields:”) +
content_tag(“ul”, object.errors.full_messages.collect {
|msg|
content_tag(“li”, msg) })+
content_tag(“ul”,relation_finder( object)),
“id” => options[:id] || “errorExplanation”, “class” =>
options[:class] || “errorExplanation”

       )
     else
       ""
     end
   end

end

def relation_finder object_name
relation_error_collector=[]
object_name.class.column_names.select{|v| v=~ /[a-z]_id/}.each do
|l|
rel=l.gsub("_id","")
obj=object_name.send(rel)
if obj != nil
relation_error_collector<<obj.errors.full_messages.collect {
|msg|
content_tag(“li”, msg) }
end
end
relation_error_collector
end

hope this helps…

regards
gaurav

You’ll probably also benefit from this:

http://i.nfectio.us/articles/2006/01/26/enhancing_rails_errors

which will allow you to consolidate the error_messages when both car
& license_instance fail to validate.

Cheers,
Michael J.