conditions on a belongs_to

52 views
Skip to first unread message

Bob Sleys

unread,
Aug 5, 2011, 1:29:03 PM8/5/11
to hobo...@googlegroups.com
Ok not exactly a Hobo specific question but I'm hoping someone here can help me out.

I have the following model
class Sample < ActiveRecord::Base

  hobo_model # Don't put anything above this
  SAMPLE_TYPES = HoboFields::Types::EnumString.for(:asbestos, :lead, :pcb)

  fields do
    sample_type Sample::SAMPLE_TYPES
    positive :boolean
    result   :string
    timestamps
  end
  inline_booleans true

  belongs_to :material
  belongs_to :location,  :class_name => "LocationMaterial", :foreign_key => :location_id, :conditions => ["location_materials.material_id = ?", 2]
  ...
end
As you can see the conditions are hard coded to material_id 2.  What I want is the ID of the material belongs_to association.  I know this looks a bit confusing as to why I would want that so I'll try to explain.

Locations have many materials and materials have many locations, classic many_to_many through locations_materials
Materials have many samples and sample belong to materials.

So far pretty straight forward.

Now samples also need to be tied back to the location they where taken from  IE I need to know not only what material was samples but where it came from.  I also need to restrict the location selection list when adding/editing samples to only locations where the material exists.  Can't sample a material where it doesn't exist after all.

Perhaps I'm barking up the wrong tree here, I've done that before so I'm open to other sugestions but it looks to me as Hobo will handle the restriction quite nicely if I can get the condition on the belongs_to to work.

Bob

kevinpfromnm

unread,
Aug 5, 2011, 6:53:13 PM8/5/11
to hobo...@googlegroups.com
I'm not certain, but I believe you can use a proc with an association to do things like this.  Haven't ever run across a need though so I can't say for certain.

Ignacio Huerta

unread,
Aug 7, 2011, 12:23:56 PM8/7/11
to hobo...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

El 05/08/11 19:29, Bob Sleys escribi�:


>
> Now samples also need to be tied back to the location they where taken from
> IE I need to know not only what material was samples but where it came
> from. I also need to restrict the location selection list when
> adding/editing samples to only locations where the material exists. Can't
> sample a material where it doesn't exist after all.

Interesting issue. In a somewhat similar case I when with a custom
action in the controller:
- - The location list is empty by default.
- - The user selects a material. A Hobo Ajax call is triggered, sending
the ID of the material.
- - The location list is updated.

It's not DRY at all, so if you find a nice solution please post :).

Regards,
Ignacio

- --
Ignacio Huerta Arteche
http://www.ihuerta.net
Tel�fono: 0034 645 70 77 35
Email realizado con software libre
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk4+vBwACgkQBPlUJ6RHaOQHzgCg98V+dR6Br2ffrVd/8ZffY/g1
XLgAn1LiL6114+F/nW5pVOr5jzsbEPBB
=o3C4
-----END PGP SIGNATURE-----

Bob Sleys

unread,
Aug 8, 2011, 12:50:51 PM8/8/11
to hobo...@googlegroups.com
Here was my solution.  I couldn't get the :conditions to accept a parameter.  It may be possible but was beyond my current skill set.

First remember I model is essentially

Locations <-> Materials -> Samples

And I'm wanting to add locations to samples but only locations where the materials exist at.

First I added a scope to Locations to find only those locations that have the given material
  scope :material_locations, lambda { |m| {
      :joins => :materials,
      :conditions => ["materials.id = ?", m.id]
  } }
Next I edited the show for materials since I'm using the embedded form to add new samples to materials via an auto_actions_for :material, [:create] in the samples controller.  I needed to get all the locations the material being samples is at.
  def show
    hobo_show do
      @material_locations = Location.material_locations(this)
    end
  end 
I had to do the same thing to the sample controller edit method for when the user edits a sample 
  def edit
    hobo_show do
      @material_locations = Location.material_locations(this.material)
    end
  end
I then edited the form for samples to limit the select-one list for the locations to use my custom lists of locations.  Note I also added a costume text-method to location since a locations could be repeated and the user wouldn't be able to tell one from another.  location_space includes the locations parent name to help distinguish them.
      <location-view:>
        <select-one options="&@material_locations" text-method="location_space" include-none="&false"/>
      </location-view:>
Now the user can only add locations to samples where the materials already exist at.

Bob


Reply all
Reply to author
Forward
0 new messages