草庐IT

php - CakePHP 3.1 patchEntity 在清洁时总是将 belongsToMany 关联标记为脏

coder 2024-04-07 原文

所以我注意到,如果我修补一个实体(编辑方法),并且如果它有 belongsToMany 关联,我是否对记录进行任何数据更改,它会将它们标记为脏。我希望如果我不对 View 中的 BTM 多选进行任何更改,数据就不会变脏,只有在多选中添加或删除选项才会在修补后将其标记为脏。

数据确实保存正确,它只是脏了,但我需要采取行动知道它是脏的还是干净的,因为我的 map 表中有 _join 数据。映射表名为 users_locations 并具有 id、user_id、location_id 和 static,其中 static 是一个 tinyint/bool。

我想做的是仅为新创建的映射表条目标记静态。

我注意到 patchEntity 正在剥离 _joinData 作为编码过程的一部分。

所以查看下面的调试输出,您可以看到在为位置和 user_occupations 都打补丁后,_joinData 被剥离了。

不知道相关数据是干净的还是脏的,这对我来说似乎是不可取的。也许它打算以这种方式工作,但我遗漏了一些东西。想法?

在我的编辑表单中:

<?php echo $this->Form->input('locations._ids', ['options' => $locations]) ?>

在我的 Controller 中:

<?php
    public function edit($id = null)
    {
        $user = $this->Users->get($id, [
            'contain' => ['Locations', 'UserOccupations']
        ]);
        if ($this->request->is(['patch', 'post', 'put'])) {
            $user = $this->Users->patchEntity($user, $this->request->data);
            if ($this->Users->save($user)) {
                $this->Flash->success(__('The user has been saved.'));
                return $this->redirect(['action' => 'index']);
            } else {
                $this->Flash->error(__('The user could not be saved. Please, try again.'));
            }
        }
        $securityGroups = $this->Users->SecurityGroups->find('list');
        $locations = $this->Users->Locations->find('list', [
            'order' => ['Locations.name' => 'ASC'],
            'keyField' => 'id',
            'valueField' => 'name',
            'limit' => 200
        ]);
        $userOccupations = $this->Users->UserOccupations->find('list');
        $this->set(compact('user', 'securityGroups', 'locations', 'userOccupations'));
        $this->set('_serialize', ['user']);
    }
?>

在模型中,我在用户的初始化函数中有这个:

$this->belongsToMany('Locations', [
    'through' => 'Users.UsersLocations',
    'foreignKey' => 'user_id',
    'targetForeignKey' => 'location_id',
    'className' => 'Locations.Locations'
]);

这是请求数据调试输出:

[
    'Referer' => [
        'url' => '/login'
    ],
    'security_group_id' => '',
    'username' => 'test',
    'email' => 'test@test.com',
    'prefix' => '',
    'first_name' => 'test',
    'middle_name' => '',
    'last_name' => 'test',
    'suffix' => '',
    'credentials' => '',
    'birthdate' => '',
    'timezone' => 'America/New_York',
    'theme' => '',
    'locations' => [
        '_ids' => [
            (int) 0 => '7',
            (int) 1 => '33'
        ]
    ],
    'user_occupations' => [
        '_ids' => [
            (int) 0 => '1'
        ]
    ]
]

这是使用请求数据修补之前的用户实体:

object(Users\Model\Entity\User) {

    'id' => '8b7197a4-5633-4bda-a6c7-a6e16f7cad64',
    'identifier' => (int) 5,
    'security_group_id' => null,
    'sex_id' => null,
    'username' => 'test',
    'email' => 'test@test.com',
    'prefix' => '',
    'first_name' => 'test',
    'middle_name' => '',
    'last_name' => 'test',
    'suffix' => '',
    'credentials' => '',
    'birthdate' => null,
    'timezone' => 'America/New_York',
    'theme' => '',
    'ip' => '0.0.0.0',
    'last_login' => null,
    'created' => object(Cake\I18n\Time) {

        'time' => '2015-09-16T16:17:57+0000',
        'timezone' => 'UTC',
        'fixedNowTime' => false

    },
    'modified' => object(Cake\I18n\Time) {

        'time' => '2015-12-16T22:22:49+0000',
        'timezone' => 'UTC',
        'fixedNowTime' => false

    },
    'user_occupations' => [
        (int) 0 => object(Users\Model\Entity\UserOccupation) {

            'id' => (int) 1,
            'name' => 'Test',
            '_joinData' => object(Cake\ORM\Entity) {

                'user_occupation_id' => (int) 1,
                'user_id' => '8b7197a4-5633-4bda-a6c7-a6e16f7cad64',
                '[new]' => false,
                '[accessible]' => [
                    '*' => true
                ],
                '[dirty]' => [],
                '[original]' => [],
                '[virtual]' => [],
                '[errors]' => [],
                '[repository]' => 'UsersUserOccupations'

            },
            '[new]' => false,
            '[accessible]' => [
                '*' => true
            ],
            '[dirty]' => [],
            '[original]' => [],
            '[virtual]' => [],
            '[errors]' => [],
            '[repository]' => 'Users.UserOccupations'

        }
    ],
    'locations' => [
        (int) 0 => object(Locations\Model\Entity\Location) {

            'id' => (int) 7,
            'ldap_name' => 'Test',
            'name' => 'Test',
            'address' => null,
            'address_2' => null,
            'city' => 'Test',
            'state' => 'MD',
            'zip' => null,
            'phone' => null,
            'fax' => null,
            'active' => true,
            'created' => object(Cake\I18n\Time) {

                'time' => '2015-09-11T19:35:34+0000',
                'timezone' => 'UTC',
                'fixedNowTime' => false

            },
            'modified' => object(Cake\I18n\Time) {

                'time' => '2015-12-16T21:47:29+0000',
                'timezone' => 'UTC',
                'fixedNowTime' => false

            },
            '_joinData' => object(Users\Model\Entity\UsersLocation) {

                'location_id' => (int) 7,
                'id' => (int) 304,
                'user_id' => '8b7197a4-5633-4bda-a6c7-a6e16f7cad64',
                'static' => false,
                '[new]' => false,
                '[accessible]' => [
                    '*' => true
                ],
                '[dirty]' => [],
                '[original]' => [],
                '[virtual]' => [],
                '[errors]' => [],
                '[repository]' => 'Users.UsersLocations'

            },
            '[new]' => false,
            '[accessible]' => [
                '*' => true
            ],
            '[dirty]' => [],
            '[original]' => [],
            '[virtual]' => [],
            '[errors]' => [],
            '[repository]' => 'Locations.Locations'

        },
        (int) 1 => object(Locations\Model\Entity\Location) {

            'id' => (int) 33,
            'ldap_name' => 'Test2',
            'name' => 'Test2',
            'address' => null,
            'address_2' => null,
            'city' => 'Test',
            'state' => 'MD',
            'zip' => null,
            'phone' => null,
            'fax' => null,
            'active' => true,
            'created' => object(Cake\I18n\Time) {

                'time' => '2015-09-15T21:03:46+0000',
                'timezone' => 'UTC',
                'fixedNowTime' => false

            },
            'modified' => object(Cake\I18n\Time) {

                'time' => '2015-12-16T21:47:29+0000',
                'timezone' => 'UTC',
                'fixedNowTime' => false

            },
            '_joinData' => object(Users\Model\Entity\UsersLocation) {

                'location_id' => (int) 33,
                'id' => (int) 305,
                'user_id' => '8b7197a4-5633-4bda-a6c7-a6e16f7cad64',
                'static' => false,
                '[new]' => false,
                '[accessible]' => [
                    '*' => true
                ],
                '[dirty]' => [],
                '[original]' => [],
                '[virtual]' => [],
                '[errors]' => [],
                '[repository]' => 'Users.UsersLocations'

            },
            '[new]' => false,
            '[accessible]' => [
                '*' => true
            ],
            '[dirty]' => [],
            '[original]' => [],
            '[virtual]' => [],
            '[errors]' => [],
            '[repository]' => 'Locations.Locations'

        },
    ],
    '[new]' => false,
    '[accessible]' => [
        '*' => true
    ],
    '[dirty]' => [],
    '[original]' => [],
    '[virtual]' => [
        (int) 0 => 'full_name',
        (int) 1 => 'name_last_first'
    ],
    '[errors]' => [],
    '[repository]' => 'Users.Users'

}

这是用请求数据修补后的调试输出的样子:

object(Users\Model\Entity\User) {

    'id' => '8b7197a4-5633-4bda-a6c7-a6e16f7cad64',
    'identifier' => (int) 5,
    'security_group_id' => null,
    'sex_id' => null,
    'username' => 'test',
    'email' => 'test@test.com',
    'prefix' => '',
    'first_name' => 'test',
    'middle_name' => '',
    'last_name' => 'test',
    'suffix' => '',
    'credentials' => '',
    'birthdate' => null,
    'timezone' => 'America/New_York',
    'theme' => '',
    'ip' => '0.0.0.0',
    'last_login' => null,
    'created' => object(Cake\I18n\Time) {

        'time' => '2015-09-16T16:17:57+0000',
        'timezone' => 'UTC',
        'fixedNowTime' => false

    },
    'modified' => object(Cake\I18n\Time) {

        'time' => '2015-12-16T22:22:49+0000',
        'timezone' => 'UTC',
        'fixedNowTime' => false

    },
    'user_occupations' => [
        (int) 0 => object(Users\Model\Entity\UserOccupation) {

            'id' => (int) 1,
            'name' => 'Test ',
            '[new]' => false,
            '[accessible]' => [
                '*' => true
            ],
            '[dirty]' => [],
            '[original]' => [],
            '[virtual]' => [],
            '[errors]' => [],
            '[repository]' => 'Users.UserOccupations'

        }
    ],
    'locations' => [
        (int) 0 => object(Locations\Model\Entity\Location) {

            'id' => (int) 7,
            'ldap_name' => 'Test',
            'name' => 'Test',
            'address' => null,
            'address_2' => null,
            'city' => 'Test',
            'state' => 'MD',
            'zip' => null,
            'phone' => null,
            'fax' => null,
            'active' => true,
            'created' => object(Cake\I18n\Time) {

                'time' => '2015-09-11T19:35:34+0000',
                'timezone' => 'UTC',
                'fixedNowTime' => false

            },
            'modified' => object(Cake\I18n\Time) {

                'time' => '2015-12-16T21:47:29+0000',
                'timezone' => 'UTC',
                'fixedNowTime' => false

            },
            '[new]' => false,
            '[accessible]' => [
                '*' => true
            ],
            '[dirty]' => [],
            '[original]' => [],
            '[virtual]' => [],
            '[errors]' => [],
            '[repository]' => 'Locations.Locations'

        },
        (int) 1 => object(Locations\Model\Entity\Location) {

            'id' => (int) 33,
            'ldap_name' => 'Test2',
            'name' => 'Test2',
            'address' => null,
            'address_2' => null,
            'city' => 'Test',
            'state' => 'MD',
            'zip' => null,
            'phone' => null,
            'fax' => null,
            'active' => true,
            'created' => object(Cake\I18n\Time) {

                'time' => '2015-09-15T21:03:46+0000',
                'timezone' => 'UTC',
                'fixedNowTime' => false

            },
            'modified' => object(Cake\I18n\Time) {

                'time' => '2015-12-16T21:47:29+0000',
                'timezone' => 'UTC',
                'fixedNowTime' => false

            },
            '[new]' => false,
            '[accessible]' => [
                '*' => true
            ],
            '[dirty]' => [],
            '[original]' => [],
            '[virtual]' => [],
            '[errors]' => [],
            '[repository]' => 'Locations.Locations'

        }
    ],
    '[new]' => false,
    '[accessible]' => [
        '*' => true
    ],
    '[dirty]' => [
        'locations' => true,
        'user_occupations' => true
    ],
    '[original]' => [
        'locations' => [
            (int) 0 => object(Locations\Model\Entity\Location) {

                'id' => (int) 7,
                'ldap_name' => 'Test',
                'name' => 'Test',
                'address' => null,
                'address_2' => null,
                'city' => 'Test',
                'state' => 'MD',
                'zip' => null,
                'phone' => null,
                'fax' => null,
                'active' => true,
                'created' => object(Cake\I18n\Time) {

                    'time' => '2015-09-11T19:35:34+0000',
                    'timezone' => 'UTC',
                    'fixedNowTime' => false

                },
                'modified' => object(Cake\I18n\Time) {

                    'time' => '2015-12-16T21:47:29+0000',
                    'timezone' => 'UTC',
                    'fixedNowTime' => false

                },
                '_joinData' => object(Users\Model\Entity\UsersLocation) {

                    'location_id' => (int) 7,
                    'id' => (int) 304,
                    'user_id' => '8b7197a4-5633-4bda-a6c7-a6e16f7cad64',
                    'static' => false,
                    '[new]' => false,
                    '[accessible]' => [
                        '*' => true
                    ],
                    '[dirty]' => [],
                    '[original]' => [],
                    '[virtual]' => [],
                    '[errors]' => [],
                    '[repository]' => 'Users.UsersLocations'

                },
                '[new]' => false,
                '[accessible]' => [
                    '*' => true
                ],
                '[dirty]' => [],
                '[original]' => [],
                '[virtual]' => [],
                '[errors]' => [],
                '[repository]' => 'Locations.Locations'

            },
            (int) 1 => object(Locations\Model\Entity\Location) {

                'id' => (int) 33,
                'ldap_name' => 'Test2',
                'name' => 'Test2',
                'address' => null,
                'address_2' => null,
                'city' => 'Test',
                'state' => 'MD',
                'zip' => null,
                'phone' => null,
                'fax' => null,
                'active' => true,
                'created' => object(Cake\I18n\Time) {

                    'time' => '2015-09-15T21:03:46+0000',
                    'timezone' => 'UTC',
                    'fixedNowTime' => false

                },
                'modified' => object(Cake\I18n\Time) {

                    'time' => '2015-12-16T21:47:29+0000',
                    'timezone' => 'UTC',
                    'fixedNowTime' => false

                },
                '_joinData' => object(Users\Model\Entity\UsersLocation) {

                    'location_id' => (int) 33,
                    'id' => (int) 305,
                    'user_id' => '8b7197a4-5633-4bda-a6c7-a6e16f7cad64',
                    'static' => false,
                    '[new]' => false,
                    '[accessible]' => [
                        '*' => true
                    ],
                    '[dirty]' => [],
                    '[original]' => [],
                    '[virtual]' => [],
                    '[errors]' => [],
                    '[repository]' => 'Users.UsersLocations'

                },
                '[new]' => false,
                '[accessible]' => [
                    '*' => true
                ],
                '[dirty]' => [],
                '[original]' => [],
                '[virtual]' => [],
                '[errors]' => [],
                '[repository]' => 'Locations.Locations'

            },
        ]
    ],
    '[virtual]' => [
        (int) 0 => 'full_name',
        (int) 1 => 'name_last_first'
    ],
    '[errors]' => [],
    '[repository]' => 'Users.Users'

}

最佳答案

请在 https://github.com/cakephp/cakephp/issues 中打开一个问题.

谢谢!

关于php - CakePHP 3.1 patchEntity 在清洁时总是将 belongsToMany 关联标记为脏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34337993/

有关php - CakePHP 3.1 patchEntity 在清洁时总是将 belongsToMany 关联标记为脏的更多相关文章

  1. ruby-on-rails - Rails 3.1 中具有相同形式的多个模型? - 2

    我正在使用Rails3.1并在一个论坛上工作。我有一个名为Topic的模型,每个模型都有许多Post。当用户创建新主题时,他们也应该创建第一个Post。但是,我不确定如何以相同的形式执行此操作。这是我的代码:classTopic:destroyaccepts_nested_attributes_for:postsvalidates_presence_of:titleendclassPost...但这似乎不起作用。有什么想法吗?谢谢! 最佳答案 @Pablo的回答似乎有你需要的一切。但更具体地说...首先改变你View中的这一行对此#

  2. ruby-on-rails - 带有 Zeus 的 RSpec 3.1,我应该在 spec_helper 中要求 'rspec/rails' 吗? - 2

    使用rspec-rails3.0+,测试设置分为spec_helper和rails_helper我注意到生成的spec_helper不需要'rspec/rails'。这会导致zeus崩溃:spec_helper.rb:5:in`':undefinedmethod`configure'forRSpec:Module(NoMethodError)对thisissue最常见的回应是需要'rspec/rails'。但这是否会破坏仅使用spec_helper拆分rails规范和PORO规范的全部目的?或者这无关紧要,因为Zeus无论如何都会预加载Rails?我应该在我的spec_helper中做

  3. ruby-on-rails - 这个 C 和 PHP 程序员如何学习 Ruby 和 Rails? - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我来自C、php和bash背景,很容易学习,因为它们都有相同的C结构,我可以将其与我已经知道的联系起来。然后2年前我学了Python并且学得很好,Python对我来说比Ruby更容易学。然后从去年开始,我一直在尝试学习Ruby,然后是Rails,我承认,直到现在我还是学不会,讽刺的是那些打着简单易学的烙印,但是对于我这样一个老练的程序员来说,我只是无法将它

  4. jquery - 如何在 rails 3.1 上安装 jQuery - 2

    我以为它已经安装了,但在我的gemfile中有gem"jquery-rails"但是在我的asset/javascripts文件夹中accounts.js.coffeeapplication.js都被注释掉了这是我的虚拟railsapplication但是在源代码中没有jQuery并且删除链接不起作用......任何想法都丢失了 最佳答案 看看thisRailscast.您可能需要检查application.js文件并确保它包含以下语句。//=requirejquery//=requirejquery_ujs

  5. ruby-on-rails - Rails 3.1,工厂女孩错误 - 2

    已修复。Rails中有一个错误。参见https://github.com/rails/rails/issues/2333我对FactoryGirlRails和Rails3.1.0.rc5有疑问当我多次执行user=FactoryGirl.create(:user)时出现错误。Failure/Error:user=FactoryGirl.create(:user)NameError:uninitializedconstantUser::User#./app/models/user.rb:17:in`generate_token'#./app/models/user.rb:4:in`blo

  6. ruby-on-rails - 让字体在 Rails 3.1 中工作? - 2

    不知道怎么回事。看来我做对了。我正在尝试使用FontAwesome在我的应用程序中,但字体没有出现。我有一个名为fonts的文件夹,在我的application.rb中包含以下行:classApplication而不是拥有Font-Awesome附带的2个css文件(更改见下文)(不需要IE7文件)我只是将主要的css放在我的应用程序.css。比我更改url来检测字体文件。@font-face{font-family:"FontAwesome";src:url('');src:url('')format('woff'),url('')format('truetype'),url('')

  7. ruby - Rails 3.1 Edge 是否破坏了 XmlMarkup::Builder? - 2

    Web上有许多示例(例如http://techoctave.com/c7/posts/32-create-an-rss-feed-in-rails)展示了如何使用Builder制作漂亮的RSS提要。规范模板是这样的:xml.instruct!:xml,:version=>"1.0"xml.rss:version=>"2.0"doxml.channeldoxml.title"YourBlogTitle"xml.description"Ablogaboutsoftwareandchocolate"xml.linkposts_urlforpostin@postsxml.itemdoxml.t

  8. ruby-on-rails - Rails 3.1 引擎迁移不起作用 - 2

    我正在创建一个带有迁移的Rails3.1引擎。rakedb:migration在该引擎和主机应用程序内部运行良好。但是我需要将这个引擎包含到另一个Rails引擎中。第二个引擎包含用于测试的虚拟应用程序,我在该虚拟应用程序的application.rb添加了这一行:require'my_engine'在控制台中,我可以看到第一个引擎的类。rake-T给我app:my_engine_engine:install:migrations任务,但是当我运行这个任务时rakeapp:my_engine_engine:install:migrations我收到这个错误:rakeaborted!Don

  9. ruby-on-rails - 移除 Rails 3.1 中的事件记录错误 - 2

    我正在将一个应用程序从Rails3.0升级到3.1,发现在我的测试中出现以下错误:NoMethodError:undefinedmethod`delete'for#我有以下移动错误的片段:after_validationdoself.errors[:image_size].eachdo|message|self.errors.add(:image,message)endself.errors[:image_extension].eachdo|message|self.errors.add(:image,message)endself.errors.delete(:image_size)

  10. ruby-on-rails - Rails 3.1 API 路由 - 2

    我有一个Rails3.1应用程序,我想为其创建一个API。我希望我的网址看起来像:www.example.com/controller/action//NormalWebrequestsapi.example.com/controller/action.json//APIrequests第一个用于正常请求,另一个显然用于我的API内容。我希望这两个都映射到同一个Controller/Action。如何设置我的应用程序,使其在www上时仅响应HTML,而在api子域上时仅响应json、xml等? 最佳答案 最简单的方法(imo)是使用

随机推荐