Ruby on rails 尝试将两个窗体从一个视图传递到两个不同的控制器
我在一个视图中有两个表单,一个在用户是版主时显示,另一个在用户是普通用户时显示,它们都将信息发送给两个不同的控制器。我的问题是,如果它是一个普通用户,那么为他们显示的表单使用了错误的控制器 这是代码 类别/new.html.erbRuby on rails 尝试将两个窗体从一个视图传递到两个不同的控制器,ruby-on-rails,ruby-on-rails-4,model-view-controller,controller,Ruby On Rails,Ruby On Rails 4,Model View Controller,Controller,我在一个视图中有两个表单,一个在用户是版主时显示,另一个在用户是普通用户时显示,它们都将信息发送给两个不同的控制器。我的问题是,如果它是一个普通用户,那么为他们显示的表单使用了错误的控制器 这是代码 类别/new.html.erb <% if current_user.mod_of_game? @guide %> <%= form_for([@guide, @category], url: guide_categories_path) do |f| %> <
<% if current_user.mod_of_game? @guide %>
<%= form_for([@guide, @category], url: guide_categories_path) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.label :name, "Category name" %>
<%= f.text_field :name %>
<%= f.submit "Next" %>
<% end %>
<% else %>
<%= form_for([@guide, @check_category], url: check_category_post_path) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.label :name, "Category name" %>
<%= f.text_field :name %>
<%= f.submit "Next" %>
<% end %>
<% end %>
检查控制器
before_action :mod_checker, only: [:create]
def new
@guide = Guide.friendly.find(params[:guide_id])
@category = Guide.friendly.find(@guide.id).categories.new
@check_category = CheckCategory.new
end
def create
@guide = Guide.friendly.find(params[:guide_id])
@category = Guide.friendly.find(@guide.id).categories.new(category_params)
if ((@category.save) && (current_user.mod_of_game? @guide))
flash[:info] = "guide category added succesfully!"
redirect_to @guide
else
render 'new'
end
end
private
def category_params
params.require(:category).permit(:name)
end
def mod_checker
@guide = Guide.friendly.find(params[:guide_id])
unless current_user.mod_of_game? @guide
flash[:danger] = "Sorry something went wrong!"
redirect_to root_path
end
end
def new
end
def create
if @check_category.save
flash[:info] = "Game category added successfully. A mod will apporve it shortly."
redirect_to @guide
else
render 'new'
end
end
private
def check_category_params
params.require(:check_category).permit(:name)
end
路线呢
resources :guides do
resources :categories, only: [:new, :create, :edit, :update]
end
resources :check_categories, only: [:new, :edit, :update]
match 'guides/:guide_id/categories/' => 'check_categories#create', :via => :post, as: :check_category_post
很抱歉,编码有点乱,在代码块中放置它的4个空格是我的编码空格
当我让非版主用户提交表单时,categories controller中的before操作将运行,我将重定向到主页。我不知道它为什么会这样做,因为对于非版主用户,提交路径应该转到check_categories控制器,check_categories控制器没有before过滤器
为什么它在我不用于该表单的控制器中使用before过滤器?我怎样才能修好它
构建此应用程序以更好地学习rails。因此,我只能假设缺乏rails知识导致我做错了什么。使用“Cancan”Gem并给予授权使用相同代码的两个表单(除了
路径
)的错误做法是违反规则的
正如@Akash
所提到的,这听起来像是一份工作
此外,它还表示代码的底层结构存在问题。具体来说,您有一个withCheckCategory
(您可以将其全部放入Category
模型中):
谢谢你的详细回答。我以前看过CanCanCan和pundit,但它们看起来更像是一个可以调节所有内容(如所有帖子)的版主。我需要它,这样只有版主的类别可以温和的什么在该类别。我有这样的设置,所以信息会进入一个单独的数据库,由mod批准,如果批准,它会移动到主数据库中显示。另外,通过这种方式,数据库显示信息的速度要快一点,因为不必先检查每一条信息是否都得到了批准。我还将拥有版本控制。如果一个普通用户编辑的信息需要首先得到mod的批准,那么CanCanCan没有那种灵活性,它需要在db中创建两条相同的记录,一条在已批准的数据库上,另一条在未批准的数据库上,而未经批准的用户则需要在其已批准的数据库上替换另一条记录。拥有2个数据库使这变得更容易和更可控。
#config/routes.rb
resources :guides do
resources :categories, only: [:new, :create, :edit, :update] do
patch :approve, on: :member
end
end
#app/models/category.rb
class Category < ActiveRecord::Base
before_action :set_guide
def new
@category = current_user.categories.new
flash[:notice] = "Since you are not a moderator, this will have to be approved." unless current_user.mod_of_game? @guide
end
def create
@category = current_user.categories.new category_params
@category.guide = @guide
@category.save
end
def approve
@category = @guide.categories.find params[:id]
@category.approve
end
private
def set_guide
@guide = Guide.find params[:guide_id]
end
end
#app/views/categories/new.html.erb
<%= form_for [@guide, @category] do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.label :name, "Category name" %>
<%= f.text_field :name %>
<%= f.submit "Next" %>
<% end %>
#app/models/category.rb
class Category < ActiveRecord::Base
enum status: [:pending, :approved]
belongs_to :user
belongs_to :guide
validates :user, :guide presence: true
before_create :set_status
def approve
self.update status: "approved"
end
private
def set_status
self[:status] = "approved" if self.user.mod_of_game? self.guide
end
end
#app/views/categories/index.html.erb
<% @categories.each do |category| %>
<%= link_to "Approve", guide_category_approve_path(@guide, category) if category.waiting? && can? :update, Category %>
<% end %>