我是使用ruby
1.9.3和rails
4.0.2和pundit
0.2.1的新手
post模型包括:
belongs_to :user
使用devise
gem生成用户模型(不有has_many :posts
吗)
devise :database_authenticatable, :registerable,
:rememberable, :trackable, :validatable
我做了rake db:drop db:create db:migrate
,我的schema.rb
现在在posts
表中有user_id
。
然后我跟随这个博客使用gem pundit
我有完全相同的代码显示在那个博客。此外,我添加了这个到我的后控制器动作:
def create
@post = Post.new(params[:post].permit(:title, :text))
authorize @post
if @post.save
redirect_to @post
else
render 'new'
end
end
def edit
@post = Post.find(params[:id])
authorize @post
end
def update
@post = Post.find(params[:id])
authorize @post
if @post.update(params[:post].permit(:title, :text))
redirect_to @post
else
render 'edit'
end
end
def destroy
@post = Post.find(params[:id])
authorize @post
@post.destroy
redirect_to posts_path
end
我没有得到任何类型的错误(NoMethodError
像我得到当我使用cancan
gem)。
但是没有用户可以编辑和销毁他的文章,即使是帖子的作者也不能。
它只是显示Couldn't find post
。(这是rescue_from
Pundit::NotAuthorizedError
的警报消息)
我尝试改变PostPolicy
owned
方法的逻辑,这是在博客文章中,但它没有工作。
我在这里尝试了其他类似的问题,但都不适合我。
由于我的授权正在工作,现在我正在努力定制views
特别是edit
和destroy
链接的帖子index.html.erb
一个帖子的唯一作者必须显示编辑和删除他的帖子的链接。
我遵循elabs/pundit使用policy方法定制视图。
这是我的代码post_policy.rb
class PostPolicy < Struct.new(:user, :post)
def owned
post.user_id == user.id
end
def create?
post.user_id = user.id
new?
end
def new?
true
end
def update?
edit?
end
def edit?
owned
end
def destroy?
owned
end
end
这是post中index.html.erb
<% if policy(Post).edit? %>
<td><%= link_to 'Edit', edit_post_path(post) %></td>
<% end %>
<% if policy(Post).destroy? %>
<td><%= link_to 'Destroy', post_path(post), method: :delete, data: { confirm: 'Are you sure?' } %></td>
<% end %>
根据pundit在elabs/pundit上的文档,它说我们可以在view
和controller
中通过policy
方法获得policy
的实例。
对我来说,它给出了NoMethodError in Posts#index
和undefined method user_id for <Class:0x22d64d8>
我有user_id字段在post。我想我需要通过@post与策略获取user_id。我试了其他方法,但都没有成功。
感谢Uri编辑这个问题。
非常感谢Andy正确地引导我。正如你所说的,user_id
对于新创建的帖子是nil。我刚刚在create
方法中将当前用户id分配给post.user_id
def create?
post.user_id = user.id
new?
end
post_policy.rb
我所有的授权现在都工作正常。
但是现在我正在努力使用用于自定义视图的策略方法。我已经编辑了相应的问题与代码。