我的应用中有以下型号
class User < ActiveRecord::Base
has_many :articles
has_many :tour_companies
has_many :accomodations
end
class Articles < ActiveRecord::Base
belongs_to :user
belongs_to :bloggable, :polymorphic => true
end
class TourCompany < ActiveRecord::Base
belongs_to :user
has_many :articles, :as => :bloggable
end
class Accommodation < ActiveRecord::Base
belongs_to :user
has_many :articles, :as => :bloggable
end
现在我的问题是我想要一个登录用户能够写一篇文章并使用表单collection_select来选择他/她的旅游公司或文章应与之相关的住宿,我该怎么做铁轨4?如何从表单集选择中选择bloggable类型和id?我不想要嵌套资源
答案 0 :(得分:5)
所以我设法终于做到了。我是怎么做到的 在views / articles / _form.html.erb
中<div class="row">
<% bloggable_collection = TourCompany.all.map{|x| [x.title, "TourCompany:#{x.id}"]} +
Accomodation.all.map{|x| [x.title, "Accomodation:#{x.id}]}
%>
<p>Select one of your listing this article is associated with</p>
<%= f.select(:bloggable, bloggable_collection,:selected =>"#{f.object.bloggable_type}:# {f.object.bloggable_id}" ) %>
</div>
然后在文章控制器中
#use regular expression to match the submitted values
def create
bloggable_params = params[:article][:bloggable].match(/^(?<type>\w+):(?<id>\d+)$/)
params[:article].delete(:bloggable)
@article = current_user.articles.build(article_params)
@article.bloggable_id = bloggable_params[:id]
@article.bloggable_type = bloggable_params[:type]
if @article.save
redirect_to admin_root_url, :notice => "Successfully created article"
else
render 'new', :alert => "There was an error"
end
end
它应该有效!
答案 1 :(得分:3)
从Rails 4.2开始,可以通过rails/globalid处理此问题。 Rails的ActiveJob使用此更新选项。它使解析和查找的设置非常简单。
首先,检查Gemfile.lock
中是否有globalid
。对于Rails 5,它是包含的。
魔术全部发生在模型中...
商品型号:
# Use :to_global_id to populate the form
def bloggable_gid
bloggable&.to_global_id
end
# Set the :bloggable from a Global ID (handles the form submission)
def bloggable_gid=(gid)
self.bloggable = GlobalID::Locator.locate gid
end
要了解它的作用,请打开rails console
。玩gid = TourCompany.first.to_global_id
和GlobalID::Locator.locate gid
。
现在您的其余代码就是股票Rails东西...
Articles Controller:
# consider building the collection in the controller.
# For Rails 5, this would be a `before_action`.
def set_bloggables
@bloggables = TourCompany.all + Accomodation.all
end
# permit :bloggable_gid if you're using strong parameters...
def article_params
params.require(:article).permit(:bloggable_gid)
end
文章表格:
<%= f.collection_select(:bloggable_gid, @bloggables, :to_global_id, :to_s) %>
有关更多演练,Simple Polymorphic Selects with Global IDs博客文章会有所帮助。