Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ember.js/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 在显示CRUD操作期间删除记录的活动模型序列化程序和权威_Ruby On Rails_Ember.js_Active Model Serializers_Json Api_Pundit - Fatal编程技术网

Ruby on rails 在显示CRUD操作期间删除记录的活动模型序列化程序和权威

Ruby on rails 在显示CRUD操作期间删除记录的活动模型序列化程序和权威,ruby-on-rails,ember.js,active-model-serializers,json-api,pundit,Ruby On Rails,Ember.js,Active Model Serializers,Json Api,Pundit,好吧,这里有些东西严重破损 我正在为我的Rails 5 JSONAPI服务器使用活动模型序列化程序和Pundit,为我的前端应用程序使用Ember 我有User模型和用户模型的权威政策,防止非作者查看未发布的故事和章节 目前,我看到一个奇怪的问题,它是这样的: 1. UserA creates StoryA, and two published chapters Chapter1 and Chapter2 2. UserA then creates two unpublished chapter

好吧,这里有些东西严重破损

我正在为我的Rails 5 JSONAPI服务器使用活动模型序列化程序和Pundit,为我的前端应用程序使用Ember

我有
User
模型和用户模型的权威政策,防止非作者查看未发布的故事和章节

目前,我看到一个奇怪的问题,它是这样的:

1. UserA creates StoryA, and two published chapters Chapter1 and Chapter2
2. UserA then creates two unpublished chapters Chapter3 and Chapter4
3. UserA logouts
4. UserB logins
5. UserB views the same story created by UserA
6. Server policy kicks in and scope the results to only published chapters since UserB isn't the author.
7. * An SQL DELETE query is sent to delete the two unpublished stories for some odd reason.
以下是一些截图:

UserA创建2个已发布的故事和2个未发布的故事

数据库记录显示4个故事属于塔贡山故事

用户A注销,用户B登录,查看Targon山的故事

(如您所见,UserB只看到两个已发布的章节,这是正确的,但是…)

由于一些奇怪的原因,未出版的章节被从数据库中删除

查看Rails控制台,我在
章控制器#show
CRUD操作期间看到了DELETE查询:

Started GET "/stories/16" for 127.0.0.1 at 2017-11-05 17:02:53 +0800
Processing by StoriesController#show as JSON
  Parameters: {"id"=>"16"}
  User Load (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 2], ["LIMIT", 1]]
  Story Load (0.1ms)  SELECT  "stories".* FROM "stories" WHERE "stories"."id" = ? LIMIT ?  [["id", 16], ["LIMIT", 1]]
  Chapter Load (0.3ms)  SELECT "chapters".* FROM "chapters" INNER JOIN "stories" ON "stories"."id" = "chapters"."story_id" INNER JOIN "users" ON "users"."id" = "stories"."user_id" WHERE "chapters"."story_id" = ? AND ((stories.published = 't' AND chapters.published = 't') OR stories.user_id = 2)  [["story_id", 16]]
  Chapter Load (0.1ms)  SELECT "chapters".* FROM "chapters" WHERE "chapters"."story_id" = ?  [["story_id", 16]]
   (0.1ms)  begin transaction
Started GET "/chapters/26" for 127.0.0.1 at 2017-11-05 17:02:53 +0800
  SQL (0.3ms)  DELETE FROM "chapters" WHERE "chapters"."id" = ?  [["id", 32]]
Started GET "/chapters/27" for 127.0.0.1 at 2017-11-05 17:02:53 +0800
Processing by ChaptersController#show as JSON
  SQL (0.1ms)  DELETE FROM "chapters" WHERE "chapters"."id" = ?  [["id", 33]]
Processing by ChaptersController#show as JSON
  Parameters: {"id"=>"26"}
   (2.1ms)  commit transaction
  Parameters: {"id"=>"27"}
  User Load (0.3ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 2], ["LIMIT", 1]]
[active_model_serializers]   User Load (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
  User Load (0.1ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 2], ["LIMIT", 1]]
  Chapter Load (0.1ms)  SELECT  "chapters".* FROM "chapters" WHERE "chapters"."id" = ? LIMIT ?  [["id", 26], ["LIMIT", 1]]
[active_model_serializers]   Story Load (0.4ms)  SELECT "stories".* FROM "stories" WHERE "stories"."user_id" = ?  [["user_id", 1]]
  Chapter Load (0.2ms)  SELECT  "chapters".* FROM "chapters" WHERE "chapters"."id" = ? LIMIT ?  [["id", 27], ["LIMIT", 1]]
Started GET "/chapters/32" for 127.0.0.1 at 2017-11-05 17:02:53 +0800
Started GET "/chapters/33" for 127.0.0.1 at 2017-11-05 17:02:53 +0800
  Story Load (0.2ms)  SELECT  "stories".* FROM "stories" WHERE "stories"."id" = ? LIMIT ?  [["id", 16], ["LIMIT", 1]]
[active_model_serializers] Rendered StorySerializer with ActiveModelSerializers::Adapter::JsonApi (22.64ms)
  Story Load (0.1ms)  SELECT  "stories".* FROM "stories" WHERE "stories"."id" = ? LIMIT ?  [["id", 16], ["LIMIT", 1]]
Processing by ChaptersController#show as JSON
Processing by ChaptersController#show as JSON
[active_model_serializers] Rendered ChapterSerializer with ActiveModelSerializers::Adapter::JsonApi (0.82ms)
Completed 200 OK in 43ms (Views: 27.1ms | ActiveRecord: 3.9ms)
我的ChaptersController show action中甚至没有“删除”或“销毁”这个词……那么记录是如何被删除的呢

# CHAPTERS CONTROLLER
def show
  chapter = Chapter.find_by(id: params[:id])

  if chapter.present?
    authorize chapter
    render json: chapter, status: :ok
  else
    skip_authorization
    render json: { error: "Chapter not found" }, status: :not_found
  end
end
我的章节策略显示方法:

# CHAPTER PUNDIT POLICY
def show?
  (@record.published? && @record.story.published?) || (@record.story.user == @user)
end
我的StoriesController显示操作如下所示:

# STORIES CONTROLLER
def show
  story = Story.find_by(id: params[:id])

  if story.present?
    authorize story
    story.chapters = policy_scope(story.chapters)
    render json: story, include: [:user, :chapters], status: :ok
  else
    skip_authorization
    render json: { errors: "Story not found" }, status: :not_found
  end
end
我想可能是Ember在幕后做了一些有趣的额外查询,但我使用Postman Mac应用程序来测试查看该故事,果然,未发布的章节在根本没有通过Ember的情况下被删除。出于某种奇怪的原因,它发生在服务器端=/


有什么想法吗?

在我看来,这实际上是在StoriesController节目中完成的。您应该再次尝试仅测试此方法(在RSpec或其他方式中),并且您还可以单步执行代码以精确定位删除发生的位置。我的猜测是:

story.chapters = policy_scope(story.chapters)
你正在改变这里的故事章节。大概你想做点什么

@displayed_chapters = policy_scope(story.chapters)

没有任何东西可以作为删除的可能来源。我认为解决方案是一些好的、老式的调试

  • 尝试注释出动作中的所有线条。然后逐个取消注释
  • 查找日志中提到的事务
  • 订阅sql查询并在查询被删除时引发,然后查看stacktrace。或者完全覆盖删除

如果删除是在序列化程序或策略中发生的,则是用户代码中的某些内容导致了删除。这两个库甚至都不知道活动记录。

注释掉该行,使其成为
#story.chapters=policy\u scope(story.chapters)
确实可以防止数据库中的记录被删除。我需要根据权威政策过滤章节,否则,我的服务器将返回所有章节,包括未发布的章节,即使对于没有创建故事的用户也是如此。有没有合适的方法过滤掉这些数据?更奇怪的是,我没有在
story.chapters=policy\u scope(story.chapters)
之后调用
story.save
,那么为什么故事会保存自己呢?好吧,没关系,我得到了为什么它会自动保存在这里的答案:文档说:
当你将一个对象分配给一个有很多关联的对象时,该对象会自动保存(为了更新其外键)。如果在一条语句中分配多个对象,那么它们都会被保存。
现在我需要研究如何过滤此行中的include字段render json:story,include:[:user,:chapters],status::ok,以便story.chapters不会返回未发布的章节,如果用户不是作者=/@Zhang,我假设您可以将授权的注释作为参数传递给序列化程序,或者覆盖序列化程序中的注释字段并在那里授权(我不确定哪一个更容易理解,但很明显,以前有人遇到过这个问题:)不确定是否有人遇到过这个问题,我的搜索结果没有返回任何类似的结果。在权威文档中,他们确实有一个关于使用
policy\u scope(@post.comments)的部分
在Rails erb html视图中,但我的前端是用Ember构建的,而不是Rails,所以我不能用Ember来实现。我甚至尝试用
jsonrails rb
gem替换活动模型序列化程序来呈现给JSONAPI,结果仍然是一样的。我已经在Pundit github问题跟踪器上发布了这个issue。这个用例看起来很简单,如果权威人士说没有办法,我会感到困惑。