我从https://gist.github.com/scttnlsn/1295485开始,作为制作一个宁静的sinatra应用程序的基础。但是,我很难管理诸如
之类的路径的HaBTM关系 delete '/:objecttype/:objid/:habtm_type/:habtm_id'
我已经有了这个对象类型,这要归功于地图(按照这个要点),并且从数据库中提取正确的对象并且ID是直接的。但是,获取habtm的另一面并在objecttype上调用适当的方法来删除关系涉及将少量字符串转换为适当的对象和方法。
我提出了一个解决方案,但它使用了eval。我知道使用eval是邪恶的,这样做会腐蚀我的灵魂。有没有更好的方法来处理这个问题,或者我应该采取一些保护措施来保护代码并将其称为一天?
这是一个有效的,独立的,无sinatra的例子来展示我如何做eval:
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
答案 0 :(得分:1)
freenode上一位优秀的绅士帮助了我。这两个版本可以替换为:
obj= self.send(relationship.to_sym).find(did)
self.send(relationship.to_sym).delete(obj)