[英]STI with a Single Controller
我有几个模型(用户,目标),我的目标模型有几个子类型(运动,瑜伽等)
用户可以有很多目标,但每种目标只能有一个。
class User < ActiveRecord::Base
has_many :goals, dependent: :destroy
has_one :exercise
has_one :water
has_one :yoga
def set_default_role
self.role ||= :user
end
end
和
class Goal < ActiveRecord::Base
self.inheritance_column = :description
belongs_to :user
validates :user_id, presence: true
validates :description, presence: true
end
目标的子类就是这样
class Exercise < Goal
belongs_to :user
end
我想在目标控制器中创建所有类型的目标,并进行设置,以便localhostL:3000 / waters / new将成为我的“水目标类型”创建页面。 我在正确设置它时遇到了麻烦,因此无法自动设置描述(我的STI列),因为我也想通过我的用户来构建它(因此也设置了user_id)。
我的目标控制器当前看起来像这样...
def create
@goal = current_user.goals.build
???? code to set goal.description = subtype that the request is coming from
respond_to do |format|
if @goal.save
format.html { redirect_to @goal, notice: 'Goal was successfully created.' }
format.json { render action: 'show', status: :created, location: @goal }
else
format.html { render action: 'new' }
format.json { render json: @goal.errors, status: :unprocessable_entity }
end
end
end
我对Rails很陌生,所以有点困惑。 也使用Rails 4.0
在这种情况下,您需要以某种方式将要创建的类型传达给控制器。
通过在表单中包含一个具有您要创建的类型的值的隐藏字段,可以最轻松地建立该字段。
假设表单的块变量为f
<%= f.hidden_field :type, :value => "Excercise" %>
然后,您可以建立一个这样的目标:
current_user.goals.build(type: params[:type])
您可以轻松地看到这是多么危险,在使用用户提交的数据时应始终加倍小心。
为了防范恶意用户,您可以在控制器中设置一个常量
AcceptedModels = ["Excercise", "Yoga", "Water"]
def accepted_type
(AcceptedModels & params[:type]).first
end
如果您还想隐藏内部结构,则可以使用哈希并发送任何标识符
AcceptedModels = {"0": "Excercise", "1": "Yoga", "2": "Water"}
def accepted_type
AcceptedModels.fetch(params[:type], nil)
end
无论哪种情况,您都可以像这样建立目标:
current_user.goals.build(type: accepted_type)
最大的缺点是,每次添加/删除更多目标时,您都必须保持AcceptedModels
更新
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.