我是一个尝试实施datagrid gem
(https://github.com/bogdan/datagrid)的新手。不幸的是,我收到三条错误消息:
Error 1: undefined method 'filter' for #<UsersGrid:0x000000044e9400>
Referring to: line `@grid.filter` in def index
Error 2: undefined local variable or method 'user' for #<UsersController:0x007f821f434808>
Referring to: line `link_to view_context.image_tag("delete.gif",...` in the controller.
Error 3: undefined method `image_tag' for UsersGrid:Class
Referring to: line `link_to image_tag(user.avatar.url,` in users_grid.rb
Placing `view_context` in front of link_to in users_grid.rb doesn't work either: undefined local variable or method 'view_context' for UsersGrid:Class.
Also tried `ActionController::Base.helpers.image_tag`. Although that seems to solve the image_tag issue, I then get the error message: `undefined method 'user_path' for #<ActionView::Base:0x007f821d3115b8>` referring to that same line.
删除上面的所有行,表单有效: - )
有关如何更改以下代码以调整这些错误的任何建议吗?
我的代码:安装完gem后我创建了/app/grids/users_grid.rb:
class UsersGrid
include Datagrid
scope do
User.order("users.created_at desc")
end
filter(:id, :integer)
filter(:email, :string) { |value| where('email like ?', "%#{value}%") }
filter(:organization, :string) { |value| where('organization like ?', "%#{value}%") }
filter(:verified, :xboolean)
filter(:created_at, :date, :range => true, :default => proc { [1.month.ago.to_date, Date.today]})
column(:id)
column(:avatar) do |user|
if user.avatar?
link_to image_tag(user.avatar.url, alt: "Profile"), user_path(user) #Error3
else
link_to image_tag("profile.gif", alt: "Profile"), user_path(user)
end
end
column(:organization)
column(:verified) do |user|
image_tag("verifiedaccount.gif", title: "verified") if user.verified
end
column(:created_at) do |model|
model.created_at.to_date
end
end
用户控制器:
def index
@grid = UsersGrid.new(params[:users_grid]) do |scope|
scope.where(admin: false).page(params[:page]).per_page(30)
end
@grid.assets
if (current_user && current_user.admin?) # This is a Sessions helper method.
@grid.filter(:activated, :xboolean, :default => true) #Error1
@grid.column(:myadmin, :header => "My admin?") do |user|
view_context.image_tag("adminamina.png", title: "admin") if user.myadmin
end
@grid.column(:activated) do |user|
user.activated_at.strftime('%v') if user.activated
end
@grid.column(:remove) do |user|
link_to view_context.image_tag("delete.gif", title: "remove"), user, method: :delete,
data: { confirm: "Please confirm" } #Error2
end
end
end
观点:
<%= datagrid_form_for @grid, :method => :get, :url => users_path %>
<%= will_paginate(@grid.assets) %>
<%= datagrid_table(@grid) %>
<%= will_paginate(@grid.assets) %>
答案 0 :(得分:2)
这个DataGrid似乎或多或少像一个Model类,我认为这是一个重要的提示,他们认真对待面向对象和封装:这个类的内部获胜&#39 ; t自动访问外部世界,您需要手动指定所需的信息。
一种称为依赖注入的技术在这里可能很有用,幸运的是DataGrid似乎对它有很好的支持。引自this wiki page:
要将对象传递给Grid实例,只需在初始化时将其合并到params散列:
grid = TheGrid.new(params[:the_grid].merge(current_user: current_user))
然后,您可以通过声明相应的getter
在Grid对象中访问它def TheGrid ... attr_accessor :current_user ... end
因此,当您new
向上移动UserGrid对象时,请指定current_user: current_user
作为哈希的一部分,然后网格应该可以访问它。
然后您还会遇到另外一个问题:UserGrid对象可以访问current_user
,但UserGrid 类会赢得,并且您已经拥有了在课堂上写下你的条件。 wiki再次为此提供了答案,它被称为dynamic columns,您可以点击该链接查看几个示例。
一个简短的动态列示例:在控制器中(或者在您创建UserGrid的任何地方),尝试类似下面的内容(再次,在上面的链接中有更多示例):
user_grid = UserGrid.new(same_params_as_before)
# The Grid object has been created, but we can still add columns to it after-the-fact
if current_user && current_user.admin?
# This block will only execute if the above condition is met. We can
# define as many extra columns as we feel like here (or change the
# user_grid object in any other way we want)
user_grid.column(:myadmin, header: "My admin?") do |user|
image_tag("adminamina.png", title: "admin") if user.myadmin
end
...
end
关于这个例子的一些注释:
current_user
。它并不关心您是管理员;控制器只是决定你是否是管理员,如果是,则对UserGrid对象进行一些更改。current_user
方法定义,以及引用它的所有代码。