【问题标题】:Rails Pundit policy_scope on render json include fields渲染 json 上的 Rails Pundit policy_scope 包含字段
【发布时间】:2017-11-06 06:25:29
【问题描述】:

继续我之前的问题:Active Model Serializer and Pundit deleting records during a Show CRUD action

我有一种情况,User 不应该能够查看其他用户的未发布章节属于作者创建的 Story

例如如果UserA 创建了一个名为Targon 的故事并提供了2 个已发布的章节和2 个未发布的章节,那么UserB 应该只能看到Targon 故事的已发布章节。

通常使用 Pundit 策略范围,它限定 index CRUD 操作。

然而,我需要在渲染 json 行期间 Chapters 属于 Story 范围:

render json: story, include: [:user, :chapters], status: :ok

我试过了:

# ---------------------------------------------------------------------------
# ActiveRecord auto-save will kick in and delete all unpublished chapters
# ---------------------------------------------------------------------------
story.chapters = policy_scope(story.chapters)

render json: story, include: [:user, :chapters], status: :ok

根据https://gist.github.com/demisx/9896113(has_many部分),当我重新分配story.chapters时,上面的代码将删除所有属于Targon的未发布章节:

story.chapters = policy_scope(story.chapters) # BAD

我希望有一些方法可以做这样的事情

render json: story, include: [:user, policy_scope(:chapters)], status: :ok

目前,在不限定 story.chapters 范围的情况下,任何获取 ID 为 16 (Targon) 的 Story 的用户都将返回 JSONAPI:

{
    "data": {
        "id": "16",
        "type": "stories",
        "attributes": {
            "title": "Mount Targon",
            "summary": "Mount Targon is the mightiest peak in Runeterra, a towering peak of sun-baked rock amid a range of summits unmatched in scale anywhere else in the world. Located far from civilization, Mount Targon is utterly remote and all but impossible to reach save by the most determined seeker. Many legends cling to Mount Targon, and, like any place of myth, it is a beacon to dreamers, madmen and questors of adventure. Some of these brave souls attempt to scale the impossible mountain, perhaps seeking wisdom or enlightenment, perhaps chasing glory or some soul-deep yearning to witness its summit. The ascent is all but impossible, and those hardy few who somehow survive to reach the top almost never speak of what they have seen. Some return with a haunted, empty look in their eyes, others changed beyond all recognition, imbued by an Aspect of unearthly, inhuman power with a destiny few mortals can comprehend.",
            "published": true,
            "published-date": "2017-11-02T10:35:33.184Z",
            "created-at": "2017-11-02T10:35:33.184Z",
            "updated-at": "2017-11-04T07:35:04.083Z",
            "cover": {
                "url": "http://res.cloudinary.com/chewedon/image/upload/v1509780931/c8ubn3tfivxziyxwynsa.png",
                "standard": {
                    "url": "http://res.cloudinary.com/chewedon/image/upload/c_fill,g_north,h_300,w_200/c8ubn3tfivxziyxwynsa.png"
                }
            }
        },
        "relationships": {
            "user": {
                "data": {
                    "id": "1",
                    "type": "users"
                }
            },
            "chapters": {
                "data": [{
                    "id": "26",
                    "type": "chapters"
                }, {
                    "id": "27",
                    "type": "chapters"
                }, {
                    "id": "37",
                    "type": "chapters"
                }, {
                    "id": "38",
                    "type": "chapters"
                }]
            }
        }
    },
    "included": [{
        "id": "1",
        "type": "users",
        "attributes": {
            "username": "Chewedon",
            "photo": {
                "url": "http://res.cloudinary.com/chewedon/image/upload/v1509857442/nx1tqlcdxrhz6r3kjx87.jpg",
                "standard": {
                    "url": "http://res.cloudinary.com/chewedon/image/upload/c_fill,g_north,h_150,w_150/nx1tqlcdxrhz6r3kjx87.jpg"
                }
            }
        },
        "relationships": {
            "stories": {
                "data": [{
                    "id": "1",
                    "type": "stories"
                }, {
                    "id": "2",
                    "type": "stories"
                }, {
                    "id": "3",
                    "type": "stories"
                }, {
                    "id": "4",
                    "type": "stories"
                }, {
                    "id": "5",
                    "type": "stories"
                }, {
                    "id": "6",
                    "type": "stories"
                }, {
                    "id": "8",
                    "type": "stories"
                }, {
                    "id": "9",
                    "type": "stories"
                }, {
                    "id": "10",
                    "type": "stories"
                }, {
                    "id": "11",
                    "type": "stories"
                }, {
                    "id": "12",
                    "type": "stories"
                }, {
                    "id": "13",
                    "type": "stories"
                }, {
                    "id": "14",
                    "type": "stories"
                }, {
                    "id": "15",
                    "type": "stories"
                }, {
                    "id": "16",
                    "type": "stories"
                }]
            }
        }
    }]
}

在关系部分,章节 3738 未发布,导致我的 Ember 前端出现 403 Forbidden。

理想情况下,服务器应该在返回记录之前将这些范围排除在外,但由于我上面描述的错误以及我之前的 Stackoverflow 问题,我被困在如何使用 Pundit 来确定包含字段的范围。

有什么想法吗?

【问题讨论】:

    标签: ruby-on-rails pundit


    【解决方案1】:

    感谢上一个链接问题中的用户 oowowaee,他建议覆盖 Story 序列化程序的 chapters 字段(我不知道你可以这样做),代码现在可以工作并且记录不会被删除来自数据库。

    class StorySerializer < ActiveModel::Serializer
      include Pundit
    
      attributes :id, :title, :summary, :published, :published_date, :created_at, :updated_at, :cover
    
      belongs_to :user
      has_many :chapters
    
      # ------------------------------------------------------------------------
      # Note: need to use 'object.chapters' not 'self.chapters` below.
      # ------------------------------------------------------------------------
      def chapters
        policy_scope(object.chapters)
      end
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-06
      • 2013-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多