尝试将2个表单从一个视图传递给2个不同的控制器

时间:2016-01-09 11:08:29

标签: ruby-on-rails ruby-on-rails-4 model-view-controller controller

我在一个视图中有两个表单如果用户是主持人,则显示一个表单;如果是普通用户,则显示另一个表单,并且他们都将信息发送到2个不同的控制器。我的问题是,如果它是普通用户,为他们显示的表单使用错误的控制器。

这是编码

类别/ new.html.erb

<% 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

check_categories控制器

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个空格是我的编码奇怪。

如果我有非主持人用户提交表单,则会运行类别控制器中的before操作,然后我将重定向到主页。我不知道为什么会这样做,因为提交路径应该转到非主持人用户的check_categories控制器,check_categories控制器没有before过滤器。

为什么它在控制器中使用之前的过滤器我没有用于那个表单?我该如何解决?

构建此应用以更好地学习rails。所以我只能假设缺乏铁路知识导致我做错了。

2 个答案:

答案 0 :(得分:1)

使用相同代码的两个表单(path除外)的不良做法违反了DRY Don't Repeat Yourself

@Akash所述,这听起来像是authorization的工作。

此外,它还表示您的代码的基础结构存在问题。具体来说,您有antipattern CheckCategory(您可以将其全部放入Category模型中):

#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

-

如果我理解正确,你想允许任何人创建一个类别,但是没有mods是由主持人“检查”他们的类别。

上面的代码应该为您实现。

您需要添加一个gem,例如 CanCan CanCanCan来实施某些授权:

#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 %>

答案 1 :(得分:0)

使用“Cancan”Gem并授权