使用相同的SAVE和UPDATE方法是不好的做法吗?

时间:2016-07-30 06:43:07

标签: php laravel eloquent

我正在使用laravel,但这并不重要,当你使用laravel命令行工具创建一个控制器时,它会在其中放置4个默认函数进行创建和更新。

对于create

storesave

editupdate代表update

这就是laravel对Shop控制器的建议。

class ShopController extends Controller
{

    public function create()
    {
       // return create view
    }

    public function store(Request $request)
    {
      // save a shop
    }

    public function edit($id)
    {
        // find a shop , return edit view
    }

    public function update(Request $request, $id)
    {
        // find the shop with id , update the shop
    }

}

但我喜欢使用相同的方法来显示视图并存储/更新我的行,并避免编写大量额外的代码。

class ShopController extends Controller
{

    public function create($id  = 0)
    {
        return view('shop-create' , ['edit'=> Shop::find($id)]);
    }

    public function store(Request $request , $id = 0 )
    {
        $whitelist = [
            'title'=>'required',
            'phone'=>'present|numeric' ,
            'address'=>'present' ,
        ];
        $this->validate($request, $whitelist );
        $shop = Shop::findOrNew($id) ;
        // find a shop with given id or create a new shop instance
        foreach($whitelist as $k=>$v)
        $shop->$k = $request[$k];

        $shop->save();
     }

}

当然,我选择了我喜欢的(第二种选择),但是由于laravel提出了第一种方式,出于好奇,我有什么理由不这样做?这在任何方面都被认为是不好的做法吗?

7 个答案:

答案 0 :(得分:3)

按照自己的方式行事并没有错。 " laravel"你提到的方式就是当你创建一个Restful resource controller时,它只是解决它的一种方法。

我猜这些控制器方法之所以被选中,是因为它们很好地排列在一个“平静的”#34;控制器的类型。如果你要建立一个真正的休息api,那么从标准的角度来看,你如何做到这一点变得更加严格(不是由laravel施加,而是更好地与laravel方式对齐)。

如果您没有创建面向公众的api,或者外部实体会消费的东西,那么我说设计最适合您和您的团队的控制器

答案 1 :(得分:3)

没错,但你的代码将难以理解,恕我直言。

e.g

  • 这种方法有什么作用?它被称为create,但它也会编辑?
  • 该视图名为shop-create,但也会编辑?
  • 传递0参数作为id的默认值,并且每次都尝试find

public function create($id  = 0)
{
    return view('shop-create' , ['edit'=> Shop::find($id)]);
}

虽然您认为自己正在简化代码,但由于您从SOLID代理Single Responsability原则,因此您将其变得更加复杂。

如果您有类似Laravel的建议,最容易理解。

此外,您保留了一个非常常见的模式,任何Laravel开发人员都会理解,因此您可以雇佣某人来处理您的代码,如果他能理解,也不用担心。

答案 2 :(得分:1)

对save()和update()使用相同的功能是个好主意,但同时它会增加复杂性。一点是如果将来你想要改变任何你只需要在一个地方改变它的东西。 但与此同时,你需要格外小心。

因为你的功能应该更有活力。

1)多个记录操作:您可能需要同时更新多个原始数据,因此您的函数应该足够灵活,可以通过相同的函数插入/更新单个/多个值。这意味着,在两种情况下都应该为多个记录触发单个查询。

2)验证值是否已存在:当您要检查某些验证时......     在插入案例中,您只需要检查db中是否存在该值 在更新的情况下,您需要检查排除当前ID e.g。

表示插入案例

 $this->validate($request, [
        'email' => 'required|string|email|unique:tablename,email'
    ]);

更新案例

  $this->validate($request, [
        'email' => 'required|string|email|unique:tablename,email,'.$id.',id'
    ]);

最后非常小的一点,但需要考虑..

3)成功消息:在插入消息时,应该"成功添加"并且在更新时间记录"已成功更新"

答案 3 :(得分:0)

我在我的最后一个项目中使用了这个方法,我们调用了store()update()函数manage(),并使用了getManage()来使用相同的视图创建和编辑。我很喜欢这种方法但却遇到了一些值得注意的事情。可悲的是,如果你不得不面对这些问题,那么利弊就会成为优点:(

<强>优点:

  • 较小的代码 - 您的store()update()函数不再有重复的代码行。
  • 如果您知道我的意思,可以更快地重复使用基本模型 - ctrl+c ctrl+v ctrl+f ctrl+r
  • 更容易添加/更改输入值 - 额外值并不意味着必须更改store()update()以确保它们都使用额外输入。
  • 一个统治它们的功能 - 只要你没有做任何特别的事情,你甚至可以为一切定义一个功能。需要改变什么?你有一个功能,不用担心。

<强>缺点:

  • 对于其他人(或年龄较大的人)来说,代码更难理解 - 如果有人不熟悉这种方法或者暂时没有使用它,那么理解你的函数中发生的事情比拥有两个独立的函数要困难一些。
  • 验证是令人讨厌的 - 如this answer中所述,验证可能因创建和更新而有所不同。这意味着您有时可能必须编写两个验证,最终会导致代码混乱,我们不希望这样!
  • 值插入并不像我想象的那么酷 - 如果你想使用相同的预定义数组来创建或更新,那么你可能会遇到想要在create上插入值但又不想更新它们的问题。这最终导致了丑陋的if语句或两个预定义的数组。

最终取决于你要做什么以及你想做什么。如果您有一个管理博客文章和网页的基本网站,则无需担心共享的store()update()功能。然而,如果您正在创建一个包含许多模型,关系以及不同创建和更新输入值的巨大CMS(这可能意味着不同的验证),那么我将使用Laravel推荐的内容。从长远来看,维护起来要容易得多,你不必处理头痛,黑客修复和不洁代码。

无论你做什么,都不要在不同的控制器中做到这两点!这会令人困惑。

顺便说一下,如果你想知道我有什么样的项目 - 这是一个巨大的CMS。因此,尽管在某些情况下它非常有用且容易,但遗憾的是它不值得。

答案 4 :(得分:0)

没有错,但在这种情况下,您必须维护正确的注释,指定您的函数执行添加/编辑,并且您正在使用某些变量,如$ id或其他东西。如果可用,则可以更新记录,否则请插入记录。

答案 5 :(得分:0)

这就是我通常这样做的方式,这样你仍然可以通过使用请求进行不同的验证,并且仍然清楚(imo)函数的作用。

public class UserResponseEvent {
    private final User user;

    public UserResponseEvent(User user) {
        this.user = user;
    }

    public User getUser() {
        return user;
    }
}

答案 6 :(得分:0)

小项目,随心所欲。与其他开发人员合作,遵循惯例。

编码约定是一组针对特定编程语言的指南,该语言建议使用该语言编写的程序的每个方面的编程样式,实践和方法。这些约定通常包括文件组织,缩进,注释,声明,语句,空格,命名约定,编程实践,编程原则,编程规则,架构最佳实践等。这些是软件结构质量的指南。强烈建议软件程序员遵循这些指南,以帮助提高源代码的可读性并简化软件维护。编码约定仅适用于软件项目的人工维护人员和同行评审人员。公约可以在整个团队或公司遵循的记录的规则集中形式化,或者可以与个人的习惯性编码实践一样非正式。编译器约定不会强制执行编码约定。 - https://en.wikipedia.org/wiki/Coding_conventions