【问题标题】:Using a key to authorise creation of model attributes使用密钥授权创建模型属性
【发布时间】:2013-05-07 10:34:04
【问题描述】:

我不确定我的逻辑在以下场景中是否正确,也许它甚至不是最佳实践,或者可能有更简单的方法。我也不确定如何设置我的代码,所以如果有人有任何指示,将不胜感激。

好的,我有两个模型

class MiniLeague < ActiveRecord::Base
  attr_accessible :league_name, :team_id, :league_key

  has_many :teams
end


class Team < ActiveRecord::Base
  attr_accessible :team_name, :user_id, :mini_league_id, :key

  belongs_to :user
  has_many :mini_leagues
end

创建迷你联赛时,会生成一个随机数(密钥),这样只有拥有该密钥的球队才能加入该联赛。密钥将传递给想要加入特定迷你联赛的用户。

我有点卡住的部分是在将球队添加到联赛时要做什么,到目前为止,我的想法是在创建球队时有一个字段来添加这个键,然后将它保存到模型中(或者如果团队已经使用密钥创建更新)。所以现在我的团队模型有一个团队名称和一个密钥。

关于如何比较这两个密钥以便只有获得授权的团队才能加入迷你联赛的任何建议。还是您会以不同的方式处理这个问题?我意识到这可能是一个很大的答案,但我很乐意接受一些指示,以便我可以找到有关如何执行此类操作的资源

谢谢

编辑

我可以在团队控制器中做类似的事情吗

Team Controller

def create
  if params[:key] && params[:mini_league_id] == params[:mini_league][:league_key] && params[:mini_league][:league_id]
  @team = Team.create(params[:team])
  else
  render :new, notice: "invalid key"
  end
 end

end

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 model key


    【解决方案1】:

    我认为最好的方法是创建一个新模型来表示 Team 和 MiniLeague 之间的联系。

    实际上,需要验证的是这种联系。另外,我猜至少理论上一个团队可以被放弃/被逐出迷你联赛;在这种情况下,您要破坏的是两个模型之间的连接。

    假设采用这种方法,您可以使用新模型中的自定义验证器检查密钥。

    所以,如果我们调用新模型,假设是 Enrollment:

    在 app/models/team.rb 中:

    class Team < ActiveRecord::Base
      attr_accessible :team_name, :user_id, :key
    
      belongs_to :user
      has_many :mini_leagues, through: enrollments
    end
    

    在 app/models/mini_league.rb 中:

    class MiniLeague < ActiveRecord::Base
      attr_accessible :league_name, :league_key
    
      has_many :teams, through: enrollments
    end
    

    在 app/models/enrollment.rb 中:

    class Enrollment < ActiveRecord::Base
       attr_accessible :team_id, :mini_league_id
    
        belongs_to :team
        belongs_to :mini_league
    
        validate :valid_key?
    
        protected
        def valid_key?
          errors.add(:base, "Invalid key") unless team.key == mini_league.league_key
        end
    end
    

    现在,注册控制器将负责创建团队和小联盟之间的连接,而不是团队控制器。

    因此,您的控制器只负责触发“保存”方法,该方法的有效或无效取决于模型逻辑,应为 (app/controllers/enrollments_controller.rb):

    class EnrollmentsController < ApplicationController
      ...
      def create
        @enrollemnt = Enrollment.new(params[:enrollment])
    
        if @enrollment.save
          # success, go on with the application flow
        else
          # error, automanaged for custom model validator if comes from a non valid league key, show the form again
          render :new
        end
      end
    end
    

    现在,如果您想显示我们在自定义验证器中创建的自定义错误消息,简单的方法是创建要插入到新团队表单中的部分:

    在您的 app/views/enrollments/_form.html.erb 中:

    <%= form_for(@enrollment) do |f| %>  
      <%= render "shared/error_messages", :target => @enrollment %> 
    
      # and then the rest of your form
      ...
    

    在 app/views/shared/error_messages 中:

    <% if target.errors.any? %>  
    <div id="errorExplanation">  
      <h2><%= pluralize(target.errors.count, "error") %> prohibited this record from being saved:</h2>  
      <ul>  
      <% target.errors.full_messages.each do |msg| %>  
        <li><%= msg %></li>  
      <% end %>  
      </ul>  
    </div>  
    <% end %>
    

    target.errors 包含错误数组,包括我们的自定义验证器之一,并且通过 full_messages 集合的迭代将显示“无效密钥”消息。

    总结一下

    创建新的注册后,相关的团队和小联盟都会响应:

    my_team.mini_leagues
    

    my_mini_league.teams
    

    【讨论】:

    • 嗨@Galen,谢谢你的帮助,快速提问,在我的else语句中我只是调用valid_key吗?方法,因为目前我得到您需要在渲染页面时提供至少一条验证错误消息
    • 我将验证更改为验证
    • 你是对的,它是验证,而不是验证。我还扩展了解释以包括如何显示自定义验证错误消息,以防万一。
    • 谢谢,这是有道理的,但仍然得到未定义的局部变量或方法`mini_league
    • 对不起@Richlewis,我没有注意到团队有_many MiniLeagues...我认为最好的方法是创建一个新模型,比如说Enrollment,来代表“加入” ,我已经相应地编辑了答案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-06
    • 1970-01-01
    相关资源
    最近更新 更多