我有几个模型(用户,目标),我的目标模型有几个子类型(运动,瑜伽等)
用户可以有多个目标,但每种类型只有一个。
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
答案 0 :(得分:1)
在这种情况下,您需要以某种方式将要创建的类型传达给控制器。
最简单的方法是在表单中包含一个隐藏字段,该字段具有您要创建的类型的值。
假设表单的块变量为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
更新