草庐IT

php - 间接修改重载属性 App\Category::$thesizes 没有效果

coder 2024-04-09 原文

对于一个网上商店,我试图生成一个如下所示的表格:

Tablename: category 1
productname     S   M   L   X  total
name1           1    0  1   3  5
name2           0    1  0   2  3


Tablename: category 2
productname     S   L   X  total
name5           1   1   3  5
name8           0   0   2  2

每个类别都有一个表格,每个类别都有自己的尺码(例如表 2 没有尺码 M)。 这些表格显示了每个类别中每种产品的每种尺寸的订购产品数量。

在应用程序中有一个模型 OrderProducts,它是每个 Order 中的订购产品。

OrderProduct 有一个 ProductSize,它是产品尺寸的联结表

ProductSize 有一个Size(其中包含尺寸的名称)

我尝试做的第一步是获取每个类别的所有尺寸/产品,例如:

    $order = Order::findOrFail($id);
    $products = OrderProduct::where('orders_id',$id)->get();

    $categories = Category::all();
    //get sizes and products per category
    foreach($categories as $cat)
    {
        $cat->thesizes= array();
        $cat->theprodcts= array();
        foreach($products as $product)
        {
            if($product->productSize->product->category_id == $cat->id)
            {
                array_push($cat->thesizes,$product->productSize);
                array_push($cat->theprodcts,$product);
            }

        }
        //make sure all values are unique (no dubbele sizes).
        $cat->theSizes = array_unique($cat->theSizes);
        $cat->theProducts = array_unique($cat->theProducts);
    }

当我运行我的代码时,出现以下错误:

Indirect modification of overloaded property App\Category::$thesizes has no effect

为什么会出现此错误,我该如何解决?

最佳答案

这是因为您的Category 类有__get()__set() magic methods实现。

所以第 7 行($cat->thesizes= array();)调用了 Category::__set() 和第 12 行(array_push($cat ->thesizes,$product->productSize);) 调用 Category::__get() 但不是 Category::__set()。因此,虽然您实现此操作的目的是将值推送到您在类别上设置的数组,但它不会起作用,因为 array_push() 正在处理返回值而不是存储在中的实际数组类别。

有几种方法可以解决这个问题。最快捷的方法是将 Category::__get() 更改为通过引用返回值,这是通过在函数的返 echo 明上使用某种类型提示来完成的

class Category
{
    public function &__get($key) {
        // body of function
    }
}

但是这可能不被推荐,如果你好奇的话,我可以谈谈原因。

更明智的方法是在循环范围内构建数组,然后将它们添加到您的 Category 对象

foreach ($categories as $cat) {
    // Scope local arrays here first
    $thesizes = array();
    $theproducts = array();

    foreach ($products as $product) {
        if ($product->productSize->product->category_id == $cat->id) {
            // Push to those local arrays
            array_push($thesizes, $product->productSize);
            array_push($theprodcts, $product);
        }
    }

    // Now assign them to the category object
    $cat->theSizes = array_unique($thesizes);
    $cat->theProducts = array_unique($theproducts);
}

如果你想获得奖励积分,因为这是 Laravel,你的返回值是 collections , 你可以做这样的事情来实现更复杂的实现

$categories = (Category::all())->map(function(Category $cat) {
    $cat->theProducts = $products
        ->filter(function(Product $product) use ($cat) {
            return $product->productSize->product->category_id == $cat->id;
        })
        ->unique();

    $cat->theSizes = $cat->theProducts
        ->map(function(Product $product) {
            return $product->productSize();
        })->unique();
});

关于php - 间接修改重载属性 App\Category::$thesizes 没有效果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38462131/

有关php - 间接修改重载属性 App\Category::$thesizes 没有效果的更多相关文章

  1. ruby - 难道Lua没有和Ruby的method_missing相媲美的东西吗? - 2

    我好像记得Lua有类似Ruby的method_missing的东西。还是我记错了? 最佳答案 表的metatable的__index和__newindex可以用于与Ruby的method_missing相同的效果。 关于ruby-难道Lua没有和Ruby的method_missing相媲美的东西吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/7732154/

  2. ruby-on-rails - 如果为空或不验证数值,则使属性默认为 0 - 2

    我希望我的UserPrice模型的属性在它们为空或不验证数值时默认为0。这些属性是tax_rate、shipping_cost和price。classCreateUserPrices8,:scale=>2t.decimal:tax_rate,:precision=>8,:scale=>2t.decimal:shipping_cost,:precision=>8,:scale=>2endendend起初,我将所有3列的:default=>0放在表格中,但我不想要这样,因为它已经填充了字段,我想使用占位符。这是我的UserPrice模型:classUserPrice回答before_val

  3. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  4. ruby-on-rails - rails 目前在重启后没有安装 - 2

    我有一个奇怪的问题:我在rvm上安装了ruby​​onrails。一切正常,我可以创建项目。但是在我输入“railsnew”时重新启动后,我有“程序'rails'当前未安装。”。SystemUbuntu12.04ruby-v"1.9.3p194"gemlistactionmailer(3.2.5)actionpack(3.2.5)activemodel(3.2.5)activerecord(3.2.5)activeresource(3.2.5)activesupport(3.2.5)arel(3.0.2)builder(3.0.0)bundler(1.1.4)coffee-rails(

  5. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

    我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

  6. ruby - 多个属性的 update_column 方法 - 2

    我有一个具有一些属性的模型:attr1、attr2和attr3。我需要在不执行回调和验证的情况下更新此属性。我找到了update_column方法,但我想同时更新三个属性。我需要这样的东西:update_columns({attr1:val1,attr2:val2,attr3:val3})代替update_column(attr1,val1)update_column(attr2,val2)update_column(attr3,val3) 最佳答案 您可以使用update_columns(attr1:val1,attr2:val2

  7. ruby - Nokogiri 剥离所有属性 - 2

    我有这个html标记:我想得到这个:我如何使用Nokogiri做到这一点? 最佳答案 require'nokogiri'doc=Nokogiri::HTML('')您可以通过xpath删除所有属性:doc.xpath('//@*').remove或者,如果您需要做一些更复杂的事情,有时使用以下方法遍历所有元素会更容易:doc.traversedo|node|node.keys.eachdo|attribute|node.deleteattributeendend 关于ruby-Nokog

  8. ruby-on-rails - Rails 模型——非持久类成员或属性? - 2

    对于Rails模型,是否可以/建议让一个类的成员不持久保存到数据库中?我想将用户最后选择的类型存储在session变量中。由于我无法从我的模型中设置session变量,我想将值存储在一个“虚拟”类成员中,该成员只是将值传递回Controller。你能有这样的类(class)成员吗? 最佳答案 将非持久属性添加到Rails模型就像任何其他Ruby类一样:classUser扩展解释:在Ruby中,所有实例变量都是私有(private)的,不需要在赋值前定义。attr_accessor创建一个setter和getter方法:classUs

  9. ruby-on-rails - 每次我尝试部署时,我都会得到 - (gcloud.preview.app.deploy) 错误响应 : [4] DEADLINE_EXCEEDED - 2

    我是Google云的新手,我正在尝试对其进行首次部署。我的第一个部署是RubyonRails项目。我基本上是在关注thisguideinthegoogleclouddocumentation.唯一的区别是我使用的是我自己的项目,而不是他们提供的“helloworld”项目。这是我的app.yaml文件runtime:customvm:trueentrypoint:bundleexecrackup-p8080-Eproductionconfig.ruresources:cpu:0.5memory_gb:1.3disk_size_gb:10当我转到我的项目目录并运行gcloudprevie

  10. ruby-on-rails - 如何重命名或移动 Rails 的 README_FOR_APP - 2

    当我在我的Rails应用程序根目录中运行rakedoc:app时,API文档是使用/doc/README_FOR_APP作为主页生成的。我想向该文件添加.rdoc扩展名,以便它在GitHub上正确呈现。更好的是,我想将它移动到应用程序根目录(/README.rdoc)。有没有办法通过修改包含的rake/rdoctask任务在我的Rakefile中执行此操作?是否有某个地方可以查找可以修改的主页文件的名称?还是我必须编写一个新的Rake任务?额外的问题:Rails应用程序的两个单独文件/README和/doc/README_FOR_APP背后的逻辑是什么?为什么不只有一个?

随机推荐