Ruby 在课堂上用绳子按摩mongoid habtm

Ruby 在课堂上用绳子按摩mongoid habtm,ruby,rest,sinatra,mongoid,eval,Ruby,Rest,Sinatra,Mongoid,Eval,我从一开始就把它作为制作restful sinatra应用程序的基础。不过,我在管理诸如以下路径的HaBTM关系方面遇到了困难: 删除“/:objecttype/:objid/:habtm\u type/:habtm\u id” 我已经有了objecttype,这多亏了map(根据这一要点),从db中提取具有id的正确对象是直截了当的。但是,获取habtm的另一面并调用objecttype上的适当方法来删除关系需要将少量字符串转换为适当的对象和方法 我想出了一个解决方案,但它使用eval。我知道

我从一开始就把它作为制作restful sinatra应用程序的基础。不过,我在管理诸如以下路径的HaBTM关系方面遇到了困难:

删除“/:objecttype/:objid/:habtm\u type/:habtm\u id”

我已经有了objecttype,这多亏了map(根据这一要点),从db中提取具有id的正确对象是直截了当的。但是,获取habtm的另一面并调用objecttype上的适当方法来删除关系需要将少量字符串转换为适当的对象和方法

我想出了一个解决方案,但它使用eval。我知道使用eval是邪恶的,这样做会腐蚀我的灵魂。有没有更好的方法来处理这个问题,或者我应该加入一些保护措施来保护代码,并就此结束

下面是一个独立的、无sinatra的工作示例,演示我是如何进行评估的:

require 'mongoid'
require 'pp'

def go
  seed

  frank = Person.find_by(name:"Frank")
  apt = Appointment.find_by(name:"Arbor day")

  pp frank
  really_a_sinatra_route(frank.id, "appointments", apt.id)
  frank.reload
  pp frank
end

def really_a_sinatra_route(id, rel_type,rel_id)
  # I use "model" in the actual app, but hardwired a person here to 
  # make a simpler example

  person  = Person.find_by(id: id)
  person.deassociate(rel_type,rel_id)
end

class Base
  def deassociate(relationship,did)
    objname = associations[relationship].class_name

    # Here's the real question... this scares me as dangerous. Is there 
    # a safer way to do this?
    obj = eval "#{objname}.find(did)"
    eval "#{relationship}.delete(obj)"
  end
end

class Person < Base
  include Mongoid::Document
  has_and_belongs_to_many :appointments

end

class Appointment < Base
  include Mongoid::Document
  has_and_belongs_to_many :persons
end

def seed
  Mongoid.configure do |config|
    config.connect_to("test_habtmexample")
  end
  Mongoid.purge!

  frank=Person.create(name:"Frank")
  joe=Person.create(name:"Joe")
  ccon = Appointment.create(name:"Comicon")
  aday = Appointment.create(name:"Arbor day")

  frank.appointments << ccon
  frank.appointments << aday
  ccon.persons << joe
  joe.reload
end

go
需要“mongoid”
需要“pp”
def go
种子
frank=人。查找方式(名称:“frank”)
apt=约会。查找人(名称:“植树节”)
弗兰克
真正的西纳特拉路线(frank.id,“约会”,apt.id)
弗兰克,重新装货
弗兰克
结束
def really_a_sinatra_路线(id,rel_类型,rel_id)
#我在实际的应用程序中使用“model”,但这里的人硬连线到
#举个简单的例子
person=person.find_by(id:id)
解除关联的人员(关系类型,关系id)
结束
阶级基础
def解除关联(关系,did)
objname=关联[关系].类名称
#这是真正的问题。。。这让我感到很危险。有
#这样做更安全吗?
obj=eval“#{objname}.find(did)”
eval“#{relationship}.delete(obj)”
结束
结束
班级人数<基数
include Mongoid::Document
有很多约会吗
结束
班级预约frank.comfreenode上的一位好绅士帮了我一把。这两个eval可以替换为:

obj= self.send(relationship.to_sym).find(did)
self.send(relationship.to_sym).delete(obj)

freenode上的一位绅士帮了我一把。这两个eval可以替换为:

obj= self.send(relationship.to_sym).find(did)
self.send(relationship.to_sym).delete(obj)