GithubHelp home page GithubHelp logo

evan / has_many_polymorphs Goto Github PK

View Code? Open in Web Editor NEW
202.0 7.0 57.0 542 KB

An ActiveRecord plugin for self-referential and double-sided polymorphic associations.

Home Page: http://blog.evanweaver.com/files/doc/fauna/has_many_polymorphs/

License: Academic Free License v3.0

Ruby 99.89% JavaScript 0.11%

has_many_polymorphs's Introduction

Has_many_polymorphs

An ActiveRecord plugin for self-referential and double-sided polymorphic associations.

DEPRECATED

No replacement.

License

Copyright 2006-2008 Cloudburst, LLC. Licensed under the AFL 3. See the included LICENSE file.

The public certificate for the gem is here.

If you use this software, please make a donation, or recommend Evan at Working with Rails.

Description

This plugin lets you define self-referential and double-sided polymorphic associations in your models. It is an extension of has_many :through.

“Polymorphic” means an association can freely point to any of several unrelated model classes, instead of being tied to one particular class.

Features

  • self-references

  • double-sided polymorphism

  • efficient database usage

  • STI support

  • namespace support

  • automatic individual and reverse associations

The plugin also includes a generator for a tagging system, a common use case (see below).

Requirements

  • Rails 2.2.2 or greater

Usage

Installation

To install the Rails plugin, run:

script/plugin install git://github.com/fauna/has_many_polymorphs.git

There’s also a gem version. To install it instead, run:

sudo gem install has_many_polymorphs

If you are using the gem, make sure to add require 'has_many_polymorphs' to environment.rb, before Rails::Initializer block.

Configuration

Setup the parent model as so:

class Kennel < ActiveRecord::Base
  has_many_polymorphs :guests, :from => [:dogs, :cats, :birds]
end

The join model:

class GuestsKennel < ActiveRecord::Base
  belongs_to :kennel
  belongs_to :guest, :polymorphic => true
end

One of the child models:

class Dog < ActiveRecord::Base
  # nothing
end

For your parent and child models, you don’t need any special fields in your migration. For the join model (GuestsKennel), use a migration like so:

class CreateGuestsKennels < ActiveRecord::Migration
  def self.up
    create_table :guests_kennels do |t|
      t.references :guest, :polymorphic => true
      t.references :kennel
    end
  end

  def self.down
    drop_table :guests_kennels
  end
end

See ActiveRecord::Associations::PolymorphicClassMethods for more configuration options.

Helper methods example

>> k = Kennel.find(1)
#<Kennel id: 1, name: "Happy Paws">
>> k.guests.map(&:class)
[Dog, Cat, Cat, Bird]

>> k.guests.push(Cat.create); k.cats.size
3
>> k.guests << Cat.create; k.cats.size
4
>> k.guests.size
6

>> d = k.dogs.first
#<Dog id: 3, name: "Rover">
>> d.kennels
[#<Kennel id: 1, name: "Happy Paws">]

>> k.guests.delete(d); k.dogs.size
0
>> k.guests.size
5

Note that the parent method is always plural, even if there is only one parent (Dog#kennels, not Dog#kennel).

See ActiveRecord::Associations::PolymorphicAssociation for more helper method details.

Extras

Double-sided polymorphism

Double-sided relationships are defined on the join model:

class Devouring < ActiveRecord::Base
  belongs_to :guest, :polymorphic => true
  belongs_to :eaten, :polymorphic => true

  acts_as_double_polymorphic_join(
    :guests =>[:dogs, :cats],
    :eatens => [:cats, :birds]
  )
end

Now, dogs and cats can eat birds and cats. Birds can’t eat anything (they aren’t guests) and dogs can’t be eaten by anything (since they aren’t eatens). The keys stand for what the models are, not what they do.

In this case, each guest/eaten relationship is called a Devouring.

In your migration, you need to declare both sides as polymorphic:

class CreateDevourings < ActiveRecord::Migration
  def self.up
    create_table :devourings do |t|
      t.references :guest, :polymorphic => true
      t.references :eaten, :polymorphic => true
    end
  end

  def self.down
    drop_table :devourings
  end
end

See ActiveRecord::Associations::PolymorphicClassMethods for more.

Tagging generator

Has_many_polymorphs includes a tagging system generator. Run:

script/generate tagging Dog Cat [...MoreModels...]

This adds a migration and new Tag and Tagging models in app/models. It configures Tag with an appropriate has_many_polymorphs call against the models you list at the command line. It also adds the file lib/tagging_extensions.rb and requires it in environment.rb.

Tests will also be generated.

Once you’ve run the generator, you can tag records as follows:

>> d = Dog.create(:name => "Rover")
#<Dog id: 3, name: "Rover">
>> d.tag_list
""
>> d.tag_with "fierce loud"
#<Dog id: 3, name: "Rover">
>> d.tag_list
"fierce loud"
>> c = Cat.create(:name => "Chloe")
#<Cat id: 1, name: "Chloe">
>> c.tag_with "fierce cute"
#<Cat id: 1, name: "Chloe">
>> c.tag_list
"cute fierce"
>> Tag.find_by_name("fierce").taggables
[#<Cat id: 1, name: "Chloe">, #<Dog id: 3, name: "Rover">]

The generator accepts the optional flag --skip-migration to skip generating a migration (for example, if you are converting from acts_as_taggable). It also accepts the flag --self-referential if you want to be able to tag tags.

See ActiveRecord::Base::TaggingExtensions, Tag, and Tagging for more.

Troubleshooting

Some debugging tools are available in lib/has_many_polymorphs/debugging_tools.rb.

If you are having trouble, think very carefully about how your model classes, key columns, and table names relate. You may have to explicitly specify options on your join model such as :class_name, :foreign_key, or :as. The included tests are a good place to look for examples.

Note that because of the way Rails reloads model classes, the plugin can sometimes bog down your development server. Set config.cache_classes = true in config/environments/development.rb to avoid this.

Reporting problems

The support forum is here.

Patches and contributions are very welcome. Please note that contributors are required to assign copyright for their additions to Cloudburst, LLC.

Further resources

has_many_polymorphs's People

Contributors

evan avatar jerome avatar levicook avatar lifo avatar loe avatar martinemde avatar niels avatar saturnflyer avatar snusnu avatar stepheneb avatar tejo avatar tylerrick avatar zef avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

has_many_polymorphs's Issues

commit bacaeb095f..., 'fix invalid byte sequence...' breaks gem on ruby 1.8.x

The new code in question is:

open(filename, :encoding=>"utf-8") do |file|

the error reported is:

open-uri.rb:32:in `initialize': can't convert Hash into String (TypeError)

The same error occurs using File.open:

File.open(filename, :encoding=>"utf-8") do |file|

Presumably this only works in Ruby 1.9. I'm building Ruby 1.9 now to check. In the latest Pickaxe book this is the method described for setting the encoding to utf-8 when using File.open:

File.open(filename, 'r:utf-8')

This method also doesn't work in 1.8.x

Also see comments on this commit:

http://github.com/fauna/has_many_polymorphs/commit/bacaeb095f5e8cf7427679b2755680ab24f8503e

Impossible to create an association with no polymorphic side.

I am using ACL ( http://github.com/rurounijones/acl9/tree/master ) for access control and combining it with has_many_polymorphs for easy associations.

It is working great with one problem. ACL9 allows you to assign roles on objects,Classes or nothing. When I assign a role on an Object or Class then everything works fine (authorizable_type is not nil in these cases). However when I add a global role ( where authorizable_type is nil) I get the following error.

  The error occurred while evaluating nil.constantize
    from (eval):7:in `before_save'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/callbacks.rb:347:in `send'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/callbacks.rb:347:in `callback'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/callbacks.rb:249:in `create_or_update'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/base.rb:2539:in `save_without_validation'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/validations.rb:1009:in `save_without_dirty'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/dirty.rb:79:in `save_without_transactions'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/transactions.rb:229:in `send'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/transactions.rb:229:in `with_transaction_returning_status'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/connection_adapters/abstract/database_statements.rb:136:in `transaction'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/transactions.rb:182:in `transaction'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/transactions.rb:228:in `with_transaction_returning_status'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/transactions.rb:196:in `save'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/transactions.rb:208:in `rollback_active_record_state!'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/transactions.rb:196:in `save'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/associations/association_collection.rb:242:in `create'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/associations/association_collection.rb:410:in `create_record'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/associations/association_collection.rb:428:in `add_record_to_target_with_callbacks'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/associations/association_collection.rb:410:in `create_record'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/associations/association_collection.rb:240:in `create'

I believe the error lies in this line:

def association_class
  @owner[@reflection.options[:foreign_type]] ? @owner[@reflection.options[:foreign_type]].constantize : nil
end

Is it possible to change this line to allow for associations where the polymorphic side is nil? In effect ignoring the :through aspect of the association record if the polymorphic side is nil and just leave it to the normal has_many.

Regards

Jeff Jones

Classes follow:

class User < ActiveRecord::Base
  has_many :roles
  has_many_polymorphs :authorizables, :from => [:committees], :through => :roles
end

class Role < ActiveRecord::Base
    belongs_to :user
    belongs_to :authorizable, :polymorphic => true
end

class Committee < ActiveRecord::Base
    has_many :accepted_roles, :as => :authorizable, :class_name => :role, :dependent => :destroy
end

association.include?(associated) fails oddly

I have a owner model:

class Person < ActiveRecord::Base
  has_many_polymorphs :things, :from => [ :books, :cds, :dvds ], :through => :person_things
end

a relationship model:

class PersonThing < ActiveRecord::Base
  belongs_to :person
  belongs_to :thing, :polymorphic => true
end 

and several owned models:

class Book < ActiveRecord::Base
end
...

If I create a relationship:

person = Person.create!(:name => 'Barney')
book = Book.create!('Dinosaurs for Dummies')
person.things << book

then include? fails even when select doesn't:

person.things.include? book
# => false
person.things.select { |t| t == book }.any?
# => true

I'm guessing include? is redefined on this enumeration, but it's not redefined correctly.

Error with the plugin...

I get this error from the plugin when I try to create a new model:

/rubyprograms/dreamstill/vendor/plugins/has_many_polymorphs/lib/has_many_polymorphs/configuration.rb:7: Configuration is not a class (TypeError)
from /Library/Ruby/Gems/1.8/gems/activesupport-3.0.4/lib/active_support/dependencies.rb:239:in require' from /Library/Ruby/Gems/1.8/gems/activesupport-3.0.4/lib/active_support/dependencies.rb:239:inrequire'
from /Library/Ruby/Gems/1.8/gems/activesupport-3.0.4/lib/active_support/dependencies.rb:225:in load_dependency' from /Library/Ruby/Gems/1.8/gems/activesupport-3.0.4/lib/active_support/dependencies.rb:596:innew_constants_in'
from /Library/Ruby/Gems/1.8/gems/activesupport-3.0.4/lib/active_support/dependencies.rb:225:in load_dependency' from /Library/Ruby/Gems/1.8/gems/activesupport-3.0.4/lib/active_support/dependencies.rb:239:inrequire'
from /rubyprograms/dreamstill/vendor/plugins/has_many_polymorphs/lib/has_many_polymorphs.rb:23
from /Library/Ruby/Gems/1.8/gems/activesupport-3.0.4/lib/active_support/dependencies.rb:239:in require' from /Library/Ruby/Gems/1.8/gems/activesupport-3.0.4/lib/active_support/dependencies.rb:239:inrequire'
from /Library/Ruby/Gems/1.8/gems/activesupport-3.0.4/lib/active_support/dependencies.rb:225:in load_dependency' from /Library/Ruby/Gems/1.8/gems/activesupport-3.0.4/lib/active_support/dependencies.rb:596:innew_constants_in'
from /Library/Ruby/Gems/1.8/gems/activesupport-3.0.4/lib/active_support/dependencies.rb:225:in load_dependency' from /Library/Ruby/Gems/1.8/gems/activesupport-3.0.4/lib/active_support/dependencies.rb:239:inrequire'
from /rubyprograms/dreamstill/vendor/plugins/has_many_polymorphs/init.rb:2
from /Library/Ruby/Gems/1.8/gems/railties-3.0.4/lib/rails/plugin.rb:81
from /Library/Ruby/Gems/1.8/gems/railties-3.0.4/lib/rails/initializable.rb:25:in instance_exec' from /Library/Ruby/Gems/1.8/gems/railties-3.0.4/lib/rails/initializable.rb:25:inrun'
from /Library/Ruby/Gems/1.8/gems/railties-3.0.4/lib/rails/initializable.rb:50:in run_initializers' from /Library/Ruby/Gems/1.8/gems/railties-3.0.4/lib/rails/initializable.rb:49:ineach'
from /Library/Ruby/Gems/1.8/gems/railties-3.0.4/lib/rails/initializable.rb:49:in run_initializers' from /Library/Ruby/Gems/1.8/gems/railties-3.0.4/lib/rails/application.rb:134:ininitialize!'
from /Library/Ruby/Gems/1.8/gems/railties-3.0.4/lib/rails/application.rb:77:in send' from /Library/Ruby/Gems/1.8/gems/railties-3.0.4/lib/rails/application.rb:77:inmethod_missing'
from /rubyprograms/dreamstill/config/environment.rb:5
from /Library/Ruby/Gems/1.8/gems/railties-3.0.4/lib/rails/application.rb:103:in require' from /Library/Ruby/Gems/1.8/gems/railties-3.0.4/lib/rails/application.rb:103:inrequire_environment!'
from /Library/Ruby/Gems/1.8/gems/railties-3.0.4/lib/rails/commands.rb:16
from script/rails:6:in `require'
from script/rails:6

What's going on here?

Development performance

The runtime performance of hmp is killing me in development mode. How can we make this better? Code generation maybe? I'm willing to help build it.

has_many_polymorphs fails with Postgres DB and columns with capitalized letters

I've been creating a rails project using has_many_polymorphs to create associations between models. Some of these models store data in columns directly related to keys in incoming/outgoing plists. This has resulted in some of the columns having capitalized names. Unfortunately, postgres automatically lowercases all characters in passed column names unless they are correctly double quoted. In its current form, has_many_polymorphs does not correctly handle this case. The error looks similar to this:

CollectionsMember Load (0.0ms) PGError: ERROR: column devices.udid does not exist
LINE 1: ...S t0_r2, collections_members.updated_at AS t0_r5, devices.Udid...

I have managed to force things to work correctly by adding quotes around column names in base.rb, function instantiate_with_polymorphic_checks, and in class_methods.rb, function build_table_aliases, though this is likely just a stop gap, as I haven't tested its effects on any other databases, and not fit for actual integration.

This issue likely effects a lot more people than just me, as this seems like a pretty common use case, and can hopefully be addressed quickly.

Creating namespaces for tags

Is it possible to specify conditions to essentially create different name spaces for tags when using the taggin_extensions? For instance, Widgets can be tagged but Widgets belong to a Company and the tag set should be specific to that company and not shared across all widgets.
Any help appreciated.

oracle support

is oracle supported?
I'm having problems with "as" keywords in joins.
... join table_name as polymorphic_parent on ...
results in missing keyword on my oracle installation. should be
... join table_name polymorphic_parent on ...
without "as"

Possible to get a tag compatible with 2.1.2

Would it be possible to get a tagged revision that works with 2.1.2? We have a rather slow-to-upgrade rails code base and I love this plugin in my other projects. Thanks if it's possible!

ActionView::TemplateError: Mysql::Error in production environment

We're getting an interesting situation where a specific series of relationships produces an unknown column error in production only.

Consider the following:
class User < ActiveRecord::Base
has_many_polymorphs :accessible_products, :through => :accessibles, :as => :contact,
:foreign_key => 'contact_id', :foreign_type_key => 'contact_type',
:polymorphic_key => 'owner_id', :polymorphic_type_key => 'owner_type',
:from => [:"product/one",:"product/two"]
end

                 class Product < ActiveRecord::Base
                 has_many_polymorphs :accessors, :through => :accessibles, :as => :owner, 
                  :foreign_key => 'owner_id', :foreign_type_key => 'owner_type',
                  :polymorphic_key => 'contact_id', :polymorphic_type_key => 'contact_type',
                  :from => [:emails, :users]
                  end

                  class Accessible < ActiveRecord::Base
                  acts_as_double_polymorphic_join :owners =>[:"product/one",:"product/two"],
                              :contacts => [:users, :emails]
                  end

This cyclical relationship should be handled by the acts_as_double_polymorphic_join but it's erroring in production, possibly due preloading of models and caching them, not sure.

The error we receive in production is ActionView::TemplateError: Mysql::Error: Unknown column 'accessibles.accessible_product_id'

The foreign and polymorphic keys are clearly defined, not sure why this is happening and only in production.

tagged_with_any: Is this tested? Supposed to work?

The tagging-extension definse two additional finders on the model, tagged_with and tagged_with_any - the code for tagged_with any (in tagging_extensions.rb) reads like this:

def self.tagged_with_any(*tag_list)

Shouldnt't this be
def tagged_with_any(*tag_list)

With the self. I get an "undefined method" but even without the self, I get a
Association named 'from' was not found; perhaps you misspelled it? (ActiveRecord::ConfigurationError)

Is this supposed to work, is it used/tested somewhere? Just asking, before I dive deeper into this and try to fix it...

thx&cheers
Stefan

P.S: Is this the right place for communication anyway? It doesn't look like anybody is looking into these issues ever, should I go ask somewhere else?!

Gem package

Hello,

I am going to create a package for Fedora. Do you have plans to release a gem?

Would be nice. Its easier and more efficient for linux distribution to track gem releases and then repack them.

polymorphic associations over different Namespaces - not possible?!

I have the following situation:

class Housing::Kennel < ActiveRecord::Base
has_many_polymorphs :guests, :from => [:dogs,:cats,_birds]
end

class GuestKennel < ActiveRecord::Base
belongs_to :kennel
belongs_to :guest, :polymorphic => true
end

class Pets::Dog < ActiveRecord::Base
end

Which I cannot get to run: (ActiveRecord::Associations::PolymorphicError: Could not find a valid class for :guests_kennels (tried GuestsKennel). If it's namespaced, be sure to specify it as :"guests/guests_kennels" instead.) - the error-message varies, depending in which module Kennel, GuestsKennel, Dog are put.

In the end, putting all three classes in one module and adding this module with :namespace => :housingandpets solves this issue.

Is there a way to specifiy the module for all three particpiants (Kennel, GuestsKennel, Dog) independently from each other and put them into different modules?!

(and thx for hmp anyway, works great!)

Double insertions into join model

I stumbled upon a situation where join model would get inserted two records whenever has_many_polymorphs was used.

Here is the scenario

class Item < ActiveRecord::Base

after_create :add_info

has_many_polymorphs :describables, :from => [:public_product_infos, :propriatary_product_infos], :through => :product_descriptions

def add_info
describables << PublicProductInfo.create(:stuff=>"blah")
end

end

I've noticed that this would insert two records into 'product_descriptions' table. Doing backtracing in debug mode it seems that the first insert is triggered by has_many_polymorphs during array append operation (as expected). However, the second one seems to be happening as if it was a regular has_many relationship. The latter one is undesirable. The fix for that was to change

after_create

to

after_save

Using :parent_extend

I was hoping somebody might point me in the right direction. I have a class Ad that has a number of different placements on a website. It has_many_polymorphs :placements, :from => [:categories, :products, :pages, :menu_items], giving me the ability to have an ad show up on a number of different models - all of this works great!

I'd like to use two more attributes on each ad - one is position for acts_as_list, and the other is location which would just be a string. I have set up the placements table with these two new fields, but I can't figure out how to extend the Ad class to include these join attributes so I can refer to these attributes when I call for child_class.ads.first.position for instance. I think I'm supposed to be using :parent_extend to assign the joined attrs to the Ad model when a child references it. Any help?

in production, undefined method, but in development - no problems

here's what I see in the console in production:
Loading production environment (Rails 2.3.11)
/opt/ruby-enterprise-1.8.7-2010.02/lib/ruby/gems/1.8/gems/activerecord-2.3.11/lib/active_record/base.rb:1998:in method_missing':NoMethodError: undefined methodhas_many_polymorphs' for #Class:0xd11d480

but in development mode, no problems.

Why would there be a difference?

my production.rb and development.rb files make no mention of has_many_polymorphs.

can't dup NilClass when trying to add an object to a list

Here is my code: http://pastie.org/456077
The first time i run it, it goes ok. The second time it blows up when i add the event to the list.

It seems the second time it passes the "if record['polymorphic_parent_class']" in base.rb. The first time it doesnt enter the if.

can't dup NilClass
/Users/magmarules/Sites/Probono/vendor/plugins/has_many_polymorphs/lib/has_many_polymorphs/base.rb:14:in dup' /Users/magmarules/Sites/Probono/vendor/plugins/has_many_polymorphs/lib/has_many_polymorphs/base.rb:14:ininstantiate'
/Library/Ruby/Gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:635:in find_by_sql' /Library/Ruby/Gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:635:incollect!'
/Library/Ruby/Gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:635:in find_by_sql' /Library/Ruby/Gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:1490:infind_every'
/Library/Ruby/Gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:589:in find' /Library/Ruby/Gems/1.8/gems/activerecord-2.2.2/lib/active_record/associations/has_many_through_association.rb:73:infind_target'
/Library/Ruby/Gems/1.8/gems/activerecord-2.2.2/lib/active_record/associations/association_collection.rb:344:in load_target' /Users/magmarules/Sites/Probono/vendor/plugins/has_many_polymorphs/lib/has_many_polymorphs/association.rb:19:in<<'
/Users/magmarules/Sites/Probono/lib/tasks/import.rake:222
/Library/Ruby/Gems/1.8/gems/rake-0.8.4/lib/rake.rb:617:in call' /Library/Ruby/Gems/1.8/gems/rake-0.8.4/lib/rake.rb:617:inexecute'
/Library/Ruby/Gems/1.8/gems/rake-0.8.4/lib/rake.rb:612:in each' /Library/Ruby/Gems/1.8/gems/rake-0.8.4/lib/rake.rb:612:inexecute'
/Library/Ruby/Gems/1.8/gems/rake-0.8.4/lib/rake.rb:578:in invoke_with_call_chain' /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/monitor.rb:242:insynchronize'
/Library/Ruby/Gems/1.8/gems/rake-0.8.4/lib/rake.rb:571:in invoke_with_call_chain' /Library/Ruby/Gems/1.8/gems/rake-0.8.4/lib/rake.rb:564:ininvoke'
/Library/Ruby/Gems/1.8/gems/rake-0.8.4/lib/rake.rb:2027:in invoke_task' /Library/Ruby/Gems/1.8/gems/rake-0.8.4/lib/rake.rb:2005:intop_level'
/Library/Ruby/Gems/1.8/gems/rake-0.8.4/lib/rake.rb:2005:in each' /Library/Ruby/Gems/1.8/gems/rake-0.8.4/lib/rake.rb:2005:intop_level'
/Library/Ruby/Gems/1.8/gems/rake-0.8.4/lib/rake.rb:2044:in standard_exception_handling' /Library/Ruby/Gems/1.8/gems/rake-0.8.4/lib/rake.rb:1999:intop_level'
/Library/Ruby/Gems/1.8/gems/rake-0.8.4/lib/rake.rb:1977:in run' /Library/Ruby/Gems/1.8/gems/rake-0.8.4/lib/rake.rb:2044:instandard_exception_handling'
/Library/Ruby/Gems/1.8/gems/rake-0.8.4/lib/rake.rb:1974:in run' /Library/Ruby/Gems/1.8/gems/rake-0.8.4/bin/rake:31 /usr/bin/rake:19:inload'
/usr/bin/rake:19

rails3

Hi,
is your plugin compatible with rails3?

HMP with accepts_nested_attributes_for breaks when assigning nested attributes

In ActiveRecord's accepts_nested_attributes_for, it uses a case statement on the reflection macro to determine the association type, and predictably, it doesn't include :has_many_polymorphs, which results in a call to a nonexistent method.

See my fork for a failing test case and possible fix for Rails 2.3.5 (test fails on master, succeeds on nested_attributes_fix branch): http://github.com/brettdh/has_many_polymorphs

I'm a Rails neophyte, so I'm not sure what would be The Right Way to fix this, since the fix requires a complete override of the relevant methods. How might I go about keeping such an override working over different Rails versions?

Multiple has_many_polymorphs in one model

I'm trying to define multiple polymorphic relations (has_many_polymorphs plugin) from a single parent to same children.

Note has many viewers
Note has many editors
Viewers could be either Users or Groups
Editors could be either Users or Groups
Permission is the association model with note_id, viewer_id, viewer_type, editor_id, editor_type fields

Everything works out as expect as long as I have only one has_many_polymorphs relation defined in Note model

class User < ActiveRecord::Base; end
class Group < ActiveRecord::Base; end

class Note < ActiveRecord::Base
    has_many_polymorphs :viewers, :through => :permissions, :from => [:users, :groups]
end

class Permission < ActiveRecord::Base
    belongs_to :note
    belongs_to :viewer, :polymorphic => true
end


Note.first.viewers << User.first # =>  [#<User id: 1, ....>]
Note.first.viewers << Group.first # =>  [#<User id: 1, ....>, #<Group ...>]
Note.first.viewers.first # => #<User ....>
Note.first.viewers.second # => #<Group ....>

Now, problems start to appear when I add the second relation

class Note < ActiveRecord::Base
    has_many_polymorphs :viewers, :through => :permissions, :from => [:users, :groups]
    has_many_polymorphs :editors, :through => :permissions, :from => [:users, :groups]
end

class Permission < ActiveRecord::Base
    belongs_to :note
    belongs_to :viewer, :polymorphic => true
    belongs_to :editor, :polymorphic => true
end

Note.first.viewers << User.first # => [#<User id: ....>]

# >>>>>>>>
Note.first.editors << User.first

NoMethodError: You have a nil object when you didn't expect it!
The error occurred while evaluating nil.constantize
... vendor/plugins/has_many_polymorphs/lib/has_many_polymorphs/base.rb:18:in `instantiate'

I've tried refining the definition of has_many_polymorphs but it didn't work. Not even with an STI model for ViewPermission < Permission, and EditPermission < Permission.

Any thoughts / workarounds / issue pointers are appreciated.

Rails 2.3.0

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.