仅更新给定对象的单个属性

时间:2019-05-12 13:42:37

标签: symfony doctrine-orm doctrine

我有一个称为worker的实体,每个工人都有一个名为active的属性,它是布尔值。

我的树枝是一个索引,显示具有active = true的工人列表。 我在每个工作人员前面都有一个按钮,当我按下此按钮时,我希望它将该工作人员的活动属性更改为false。

问题:我无法弄清楚如何在不生成表单的情况下更改控制器中的值,因为在Symfony方面我还是一个业余爱好者

这是我的树枝:


<table id="file_export" class="table table-striped table-bordered">

        <thead>
            <tr>
                <th>ID</th>
                <th>First Name</th>
                <th>Last name</th>
                <th>Active</th>
                <th>edit</th>
            </tr>
        </thead>
        <tbody>
        {% for worker in workers %}
            <tr>
                <td>{{ worker.id }}</td>
                <td>{{ worker.Firstname }}</td>
                <td>{{ woker.Lastname }}</td>
                <td>{{ worker.active ? 'active' : 'inactive' }}</td>
                <td>
                    <a href="{{ path('worker_edit', {'id': worker.id}) }}" class="btn btn-round btn-info" role="button"><i class="fa fa-pencil"></i></a>
                </td>
            </tr>
        {% endfor %}
        </tbody>
    </table>

和我的控制器(不起作用):

    /**
     * @Route("/{id}/edit", name="worker_edit", methods={"GET","POST"})
     */
    public function edit(Request $request, Worker $worker): Response
    {
        if ($this->isCsrfTokenValid('edit'.$worker->getId(), $request->request->get('_token'))) {
            $worker->setActive(false);

            $entityManager = $this->getDoctrine()->getManager();
            $entityManager->persist($worker);
            $entityManager->flush();
        }

        return $this->redirectToRoute('index');
    }

2 个答案:

答案 0 :(得分:1)

您实际上必须在路径调用中添加一个csrf令牌:

path('worker_edit', {'id': worker.id, '_token': csrf_token('worker'~worker.id)}) 

否则,您对csrf令牌的检查显然无法成功。

但是,由于链接将触发GET请求,因此您必须调查

$request->query->get('_token')

isCsrfTokenValid通话中。

作为提示:为您的路线和动作提供语义上更好的名称。类似于...“ worker_deactivate”,如果它用于停用某个工作程序(显然是这样)。 调用控制器 action Action的路由方法也是很普遍的,所以将其称为deactivateAction

答案 1 :(得分:-1)

如果您想发出HTTP请求而不重新加载网页,则必须进行AJAX调用。使用fetch的非常简单的实现,不需要任何其他程序包(如jQuery),如下所示:

<script>
(function() {
    document.getElementById({{worker.id}}).addEventListener('click', function(e) {
        e.preventDefault();
        fetch({{path('worker_edit', {'id': worker.id})}}, {method: 'POST'})
            .then(function(response) {
                // you can catch eventual errors here, and of course refresh your button or display a nice message..

            });
    });
})()
</script>
<table id="file_export" class="table table-striped table-bordered">

        <thead>
            <tr>
                <th>ID</th>
                <th>First Name</th>
                <th>Last name</th>
                <th>Active</th>
                <th>edit</th>
            </tr>
        </thead>
        <tbody>
        {% for worker in workers %}
            <tr>
                <td>{{ worker.id }}</td>
                <td>{{ worker.Firstname }}</td>
                <td>{{ woker.Lastname }}</td>
                <td>{{ worker.active ? 'active' : 'inactive' }}</td>
                <td>
                    <a href="{{ path('worker_edit', {'id': worker.id}) }}" class="btn btn-round btn-info" role="button"><i class="fa fa-pencil"></i></a>
                </td>
            </tr>
        {% endfor %}
        </tbody>
    </table>

p.s:上面的javascript代码未经测试,因为我必须重现树枝和控制器,但是它可以为您提供有关如何完成任务的想法。