Flourish PHP Unframework
This is an archived copy of the forum for reference purposes

fActiveRecord::associate pluralisation

posted by vena 9 years ago

I'm not sure what's happening here, but it seems like flourish looks for the class name without taking pluralisation into account if it's given an array with only one member. For instance, if i do $groups->associateGroupFields($fields) but $fields is an array with a count of 1, it will cause a fatal "class GroupFields not found" error, however if the array count is > 1, it recognises the pluralisation correctly and calls the GroupField class.

for example, check out this trace:

Fatal error: Class 'GroupFields' not found in /application/libraries/flourish/fORMRelated.php on line 107
Call Stack
#	Time	Memory	Function	Location
1	0.0007	84544	{main}( )	../index.php:0
2	0.0016	94380	require( '/application/bootstrap.php' )	../index.php:49
3	0.1916	8140364	Router::run( )	../bootstrap.php:86
4	0.1917	8140660	Router::matchURLToRoute( )	../Router.php:175
5	0.1924	8143624	Router::dispatch( )	../Router.php:142
6	0.3036	8292800	SurveyController->processEditSurvey( )	../Router.php:104
7	0.3449	8463332	SurveyGroup->associateGroupFields( )	../SurveyController.php:192
8	0.3449	8463712	fActiveRecord->__call( )	../fActiveRecord.php:0
9	0.3454	8466104	fORMRelated::associateRecord( )	../fActiveRecord.php:811

and here's the creates for the tables...

CREATE TABLE IF NOT EXISTS `surveys` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `creator` bigint(20) unsigned NOT NULL,
  `title` varchar(255) NOT NULL,
  `date_updated` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `date_created` timestamp NULL DEFAULT '0000-00-00 00:00:00',
  PRIMARY KEY (`id`),
  KEY `creator` (`creator`),
  KEY `theme` (`theme`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='surveys' AUTO_INCREMENT=1 ;

CREATE TABLE IF NOT EXISTS `survey_groups` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `survey_id` bigint(20) unsigned DEFAULT NULL,
  `display_order` int(10) unsigned DEFAULT NULL,
  `label` varchar(255) DEFAULT NULL,
  `type` varchar(150) NOT NULL DEFAULT '',
  `date_updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `date_created` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  PRIMARY KEY (`id`),
  UNIQUE KEY `display_order` (`survey_id`,`display_order`),
  KEY `survey_id` (`survey_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COMMENT='survey groups' AUTO_INCREMENT=7 ;
ALTER TABLE `survey_groups`
  ADD CONSTRAINT `survey_groups_ibfk_1` FOREIGN KEY (`survey_id`) REFERENCES `surveys` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;

CREATE TABLE IF NOT EXISTS `survey_group_fields` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `group_id` bigint(20) unsigned DEFAULT NULL,
  `display_order` int(10) unsigned DEFAULT NULL,
  `type` varchar(150) NOT NULL,
  `label` varchar(255) DEFAULT NULL,
  `default_value` varchar(250) DEFAULT NULL,
  `selected` tinyint(1) DEFAULT '0',
  `max_length` int(3) unsigned DEFAULT NULL,
  `validation_regexp` varchar(255) DEFAULT NULL,
  `required` tinyint(1) DEFAULT '0',
  `date_updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `date_created` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  PRIMARY KEY (`id`),
  UNIQUE KEY `display order` (`group_id`,`display_order`),
  KEY `group_id` (`group_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='survey group fields' AUTO_INCREMENT=1 ;
ALTER TABLE `survey_group_fields`
  ADD CONSTRAINT `survey_group_fields_ibfk_2` FOREIGN KEY (`group_id`) REFERENCES `survey_groups` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;

For reference, this is from code gleened from this previous thread re: deep relations.

Any ideas here? It's got me stuck pretty bad.

If i duplicate the models and create new ones like "GroupFields" to try and get around the pluralisation issue, I just end up with a different exception claiming i have an invalidly formatted primary or unique key:

object(fProgrammerException)[19]
  protected 'message' => string 'An invalidly formatted primary or unique key was passed to this Group Fields object' (length=83)
  private 'string' => string '' (length=0)
  protected 'code' => null
  protected 'file' => string '/application/libraries/flourish/fActiveRecord.php' (length=119)
  protected 'line' => int 1119
  private 'trace' => 
    array
      0 => 
        array
          'file' => string '/application/libraries/flourish/fORMRelated.php' (length=117)
          'line' => int 107
          'function' => string '__construct' (length=11)
          'class' => string 'fActiveRecord' (length=13)
          'type' => string '->' (length=2)
          'args' => 
            array
              0 => 
                array
                  0 => 
                    object(GroupField)[18]
                      protected 'cache' => 
                        array
                          empty
                      protected 'old_values' => 
                        array
                          'selected' => 
                            array
                              0 => null
                          'required' => 
                            array
                              0 => null
                          'date_updated' => 
                            array
                              0 => null
                          'date_created' => 
                            array
                              0 => null
                          'display_order' => 
                            array
                              0 => null
                          'type' => 
                            array
                              0 => null
                          'default_value' => 
                            array
                              0 => null
                          'max_length' => 
                            array
                              0 => null
                          'validation_regexp' => 
                            array
                              0 => null
                      protected 'related_records' => 
                        array
                          empty
                      protected 'values' => 
                        array
                          'id' => null
                          'group_id' => null
                          'display_order' => null
                          'type' => string 'text' (length=4)
                          'label' => null
                          'default_value' => null
                          'selected' => boolean false
                          'max_length' => string '100' (length=3)
                          'validation_regexp' => null
                          'required' => boolean false
                          'date_updated' => 
                            object(fTimestamp)[17]
                              private 'timestamp' => int 1265589534
                              private 'timezone' => string 'UTC' (length=3)
                          'date_created' => string '0000-00-00 00:00:00' (length=19)
      1 => 
        array
          'file' => string '/application/libraries/flourish/fActiveRecord.php' (length=119)
          'line' => int 811
          'function' => string 'associateRecord' (length=15)
          'class' => string 'fORMRelated' (length=11)
          'type' => string '::' (length=2)
          'args' => 
            array
              0 => string 'SurveyGroup' (length=11)
              1 => &
                array
                  empty
              2 => string 'GroupFields' (length=11)
              3 => 
                array
                  0 => 
                    object(GroupField)[18]
                      protected 'cache' => 
                        array
                          empty
                      protected 'old_values' => 
                        array
                          'selected' => 
                            array
                              0 => null
                          'required' => 
                            array
                              0 => null
                          'date_updated' => 
                            array
                              0 => null
                          'date_created' => 
                            array
                              0 => null
                          'display_order' => 
                            array
                              0 => null
                          'type' => 
                            array
                              0 => null
                          'default_value' => 
                            array
                              0 => null
                          'max_length' => 
                            array
                              0 => null
                          'validation_regexp' => 
                            array
                              0 => null
                      protected 'related_records' => 
                        array
                          empty
                      protected 'values' => 
                        array
                          'id' => null
                          'group_id' => null
                          'display_order' => null
                          'type' => string 'text' (length=4)
                          'label' => null
                          'default_value' => null
                          'selected' => boolean false
                          'max_length' => string '100' (length=3)
                          'validation_regexp' => null
                          'required' => boolean false
                          'date_updated' => 
                            object(fTimestamp)[17]
                              private 'timestamp' => int 1265589534
                              private 'timezone' => string 'UTC' (length=3)
                          'date_created' => string '0000-00-00 00:00:00' (length=19)
              4 => null
      2 => 
        array
          'function' => string '__call' (length=6)
          'class' => string 'fActiveRecord' (length=13)
          'type' => string '->' (length=2)
          'args' => 
            array
              0 => string 'associateGroupFields' (length=20)
              1 => 
                array
                  0 => 
                    array
                      0 => 
                        object(GroupField)[18]
                          protected 'cache' => 
                            array
                              empty
                          protected 'old_values' => 
                            array
                              'selected' => 
                                array
                                  0 => null
                              'required' => 
                                array
                                  0 => null
                              'date_updated' => 
                                array
                                  0 => null
                              'date_created' => 
                                array
                                  0 => null
                              'display_order' => 
                                array
                                  0 => null
                              'type' => 
                                array
                                  0 => null
                              'default_value' => 
                                array
                                  0 => null
                              'max_length' => 
                                array
                                  0 => null
                              'validation_regexp' => 
                                array
                                  0 => null
                          protected 'related_records' => 
                            array
                              empty
                          protected 'values' => 
                            array
                              'id' => null
                              'group_id' => null
                              'display_order' => null
                              'type' => string 'text' (length=4)
                              'label' => null
                              'default_value' => null
                              'selected' => boolean false
                              'max_length' => string '100' (length=3)
                              'validation_regexp' => null
                              'required' => boolean false
                              'date_updated' => 
                                object(fTimestamp)[17]
                                  private 'timestamp' => int 1265589534
                                  private 'timezone' => string 'UTC' (length=3)
                              'date_created' => string '0000-00-00 00:00:00' (length=19)
      3 => 
        array
          'file' => string '/application/controllers/admin/SurveyController.php' (length=121)
          'line' => int 196
          'function' => string 'associateGroupFields' (length=20)
          'class' => string 'SurveyGroup' (length=11)
          'type' => string '->' (length=2)
          'args' => 
            array
              0 => 
                array
                  0 => 
                    object(GroupField)[18]
                      protected 'cache' => 
                        array
                          empty
                      protected 'old_values' => 
                        array
                          'selected' => 
                            array
                              0 => null
                          'required' => 
                            array
                              0 => null
                          'date_updated' => 
                            array
                              0 => null
                          'date_created' => 
                            array
                              0 => null
                          'display_order' => 
                            array
                              0 => null
                          'type' => 
                            array
                              0 => null
                          'default_value' => 
                            array
                              0 => null
                          'max_length' => 
                            array
                              0 => null
                          'validation_regexp' => 
                            array
                              0 => null
                      protected 'related_records' => 
                        array
                          empty
                      protected 'values' => 
                        array
                          'id' => null
                          'group_id' => null
                          'display_order' => null
                          'type' => string 'text' (length=4)
                          'label' => null
                          'default_value' => null
                          'selected' => boolean false
                          'max_length' => string '100' (length=3)
                          'validation_regexp' => null
                          'required' => boolean false
                          'date_updated' => 
                            object(fTimestamp)[17]
                              private 'timestamp' => int 1265589534
                              private 'timezone' => string 'UTC' (length=3)
                          'date_created' => string '0000-00-00 00:00:00' (length=19)

is there something i'm missing here in my schema or something? i can't figure out what's going wrong here...

posted by vena 9 years ago

uhm, ok... so... i rebuilt the database using single names rather than underscore notation, and changed the name of the classes so they're the exact, singular form of the database tables (i was using fORM::mapClassToTable before), and now it works and i'm further confused.

here are the new creates in case you can spot something here

-- --------------------------------------------------------

--
-- Table structure for table `fields`
--

CREATE TABLE IF NOT EXISTS `fields` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `group_id` bigint(20) unsigned NOT NULL,
  `display_order` int(10) NOT NULL,
  `type` varchar(100) NOT NULL,
  `label` varchar(255) NOT NULL,
  `default_value` varchar(255) NOT NULL,
  `max_length` int(4) NOT NULL,
  `validation_regexp` varchar(255) NOT NULL,
  `selected` tinyint(1) NOT NULL,
  `required` tinyint(1) NOT NULL,
  `date_updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `date_created` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  PRIMARY KEY (`id`),
  UNIQUE KEY `display_order` (`group_id`,`display_order`),
  KEY `group_id` (`group_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

-- --------------------------------------------------------

--
-- Table structure for table `groups`
--

CREATE TABLE IF NOT EXISTS `groups` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `survey_id` bigint(20) unsigned NOT NULL,
  `display_order` int(10) NOT NULL,
  `type` varchar(100) NOT NULL,
  `label` varchar(255) NOT NULL,
  `sublabel` varchar(255) NOT NULL,
  `date_updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `date_created` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  PRIMARY KEY (`id`),
  UNIQUE KEY `display_order` (`survey_id`,`display_order`),
  KEY `survey_id` (`survey_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

-- --------------------------------------------------------

--
-- Table structure for table `surveys`
--

CREATE TABLE IF NOT EXISTS `surveys` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `creator` bigint(20) unsigned NOT NULL,
  `theme` bigint(20) unsigned DEFAULT NULL,
  `title` varchar(255) NOT NULL,
  `thanks` varchar(255) DEFAULT NULL,
  `start_date` timestamp NULL DEFAULT '0000-00-00 00:00:00',
  `end_date` timestamp NULL DEFAULT '0000-00-00 00:00:00',
  `date_updated` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `date_created` timestamp NULL DEFAULT '0000-00-00 00:00:00',
  PRIMARY KEY (`id`),
  KEY `creator` (`creator`),
  KEY `theme` (`theme`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='surveys' AUTO_INCREMENT=1 ;

--
-- Constraints for dumped tables
--

--
-- Constraints for table `fields`
--
ALTER TABLE `fields`
  ADD CONSTRAINT `fields_ibfk_1` FOREIGN KEY (`group_id`) REFERENCES `groups` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;

--
-- Constraints for table `groups`
--
ALTER TABLE `groups`
  ADD CONSTRAINT `groups_ibfk_1` FOREIGN KEY (`survey_id`) REFERENCES `surveys` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;

--
-- Constraints for table `surveys`
--
ALTER TABLE `surveys`
  ADD CONSTRAINT `surveys_ibfk_1` FOREIGN KEY (`creator`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;

admittedly, i've been working on this all day so my brain my be a little run down. maybe all this data can help you figure this out, i'm just glad it's working :)

posted by vena 9 years ago

I wanted to let you guys know that all issues with mapped classes should be resolved as of r792.

I also updated the documentation about fORM::mapClassToTable() to recommend calling it in site-wide configuration and not in fActiveRecord::configure().

posted by wbond 9 years ago

I think it has to do with the fact that there is an associate for *-to-many relationships, but there is also an associate for one-to-one relationships. My guess is that the code I have right now probably isn't robust enough to handle mapped class names. I'll try to look into this soon - I'm just finishing up a major patch to Flourish.

posted by wbond 9 years ago

Same problem here.

Just FYI, if i use mapped table names, for example for users and groups, both $user->associateGroup($one_group) and $user->associateGroups($groups_array) wont work.

How can I associate user and groups in the meantime? should I make: $ref = new UserGroup(), set user_id and group_id and then $ref->store() ?

posted by aurelien 9 years ago

In another thread, there was some thought that calling fORM::mapClassToTable() for each model that needs table mapping in your init script rather than in the individual models' configure() methods might work.

posted by vena 9 years ago

Yep I emmited that idea :) but in my case the association with mapped table names does not work even if the mapping is done

posted by aurelien 9 years ago