我正在尝试通过has_many :through
关系获取值。三个主要数据库:人员,位置(具有街道地址和其他信息)以及联接表years
,联接表将人员在特定日期链接到特定地址。
# models/person.rb
class Person < ApplicationRecord
has_many :years, dependent: :destroy
has_many :locations, through: :years
# models/location.rb
class Location < ApplicationRecord
has_many :years
has_many :people, through: :years
# models/year.rb
class Year < ApplicationRecord
belongs_to :location
belongs_to :person
[years
将人员链接到特定日期的特定地址。
据我所知,流程是show.html.erb
调用javascript/packs/olPeopleMap.js
,然后调用show_locations.json.jbuilder
。如何将person.id
传递给jbuilder?
来自views/people/show.html.erb
(当然是特定人员的页面,我希望显示该人员的详细信息,包括与他们相关的位置)。
<div id="map" class="map"></div>
<%= javascript_pack_tag 'olPeopleMap' %>
<div>
从javascript/packs/olPeopleMap.js
当然不知道这是谁。
new VectorImageLayer({
title: 'Where lived and worked',
imageRatio: 2,
source: new VectorSource({
url: '../people/show_locations', // Doesn't know which person I want
format: new GeoJSON()
}),
无法正常工作的代码,因为它不知道person_id(代码可能还有其他问题:]
# …/show_locations.json.jbuilder,
json.type "FeatureCollection"
json.features @person.years do |year|
# Person has_many :locations, through: :years
json.type "Feature"
json.properties do
json.set! "marker-color", "#C978F3" # will make this different for resto and resid a
# json.title year.resto
json.name year.full_name
end
json.geometry do
json.type "Point"
json.coordinates [year.location['longitude'], year.location['latitude']]
end # json.geometry
end # features
[在views/people/show.html.erb
中确认模型正在工作,(删除了大多数格式):
<% for year in @person.years %>
<%= year.year_date.strftime('%-d' ' ' '%b' ' ' '%Y') %>,
<%= year.title %>,
<%= link_to(year.location) do %>,
<%= year.location.address %>,
<% end %>,
<%= year.resto_name %>.
<% end %>
例如,产生1 Sep 1895, Co-proprietor, , 128 E 1st St, , Commercial Restaurant and Oyster Parlor.
的作品当然是year.location.address
至location
。链接是years
。
总之,如何将person.id传递给jBuilder?还是我会错了?
您可以使用HTML http://localhost:3000/locations/140
属性简单地传递id
或完整的操作URL(我希望这样做)。
show.html.erb
data
javascript / packs / olPeopleMap.js
<div id="person-details" data-url="<%= @person.id %>"></div>
首先设置一个嵌套路由,该路由提供要使用的JSON:
new VectorImageLayer({
title: 'Where lived and worked',
imageRatio: 2,
source: new VectorSource({
url: `../people/show_locations/${$('#person-details').data('id')}`,
format: new GeoJSON()
}),
resources :people do
resources :locations, only: :index, module: :people
end
重命名视图module People
class LocationsController
# GET /people/1/locations.json
def index
@person = Person.includes(:locations).find(params[:person_id])
@locations = @person.locations
end
end
end
。
然后在视图中设置地图容器:
app/views/people/locations/index.json.jbuilder
[如果您以正确的方式进行操作,则没有理由接近<div id="map" class="map" data-url="<%= person_locations_path(@person) %>">
</div>
的废话,因为它使您的服务器陷入了客户端的状态,因而使所有事情变得一团糟。
请勿尝试在不同页面上放置不同的脚本标签。这不是一个好方法-特别是在涉及Turbolink的情况下。如果在“静态” .js.erb
目录中存在的话(在本例中为#map元素),请创建处理程序以扩大页面上的不同元素。
这将关注点分离到位-服务器只提供客户端使用的数据,它允许您的JavaScript通过CDN进行连接,缩小,缓存和传递,而不是让Rails提供插值的/javascripts/packs
汤。
这还避免了将Rails应用程序变成一堆仅更新客户端的RPC样式路由。
在OpenLayers中,您应该能够通过地图的target属性获得地图所绑定的元素。
.js.erb
Rails在服务器上运行,JavaSciprt是脚本语言在浏览器(客户端)上运行。基本上,没有办法将数据从Rails直接传递到Javascript。因此,您需要第三次存储以在Rails和Javascript之间传递数据,例如HTML数据属性,隐藏的HTML字段,...]