如何将关联加载到实例变量?

时间:2017-03-05 08:09:51

标签: ruby-on-rails ruby ruby-on-rails-5 model-associations react-rails

在模型中我有:

class CalendarItem < Resource
  belongs_to :schedule

  has_many :people
  has_many :documents

  acts_as_list scope: :schedule, column: :visual_position

  validates :schedule, :title, presence: true
end

然后在控制器中:

class ScheduleController < ApplicationController
  def show
    @calendar_items = CalendarItem.where(schedule: @schedule).includes(:people, :documents)
  end

  ...
end

在视图中,我使用react-rails渲染react_component(但这应该有所不同):

= react_component('CalendarItemsList', calendar_items: @calendar_items)

但是它不会将关联数据传递给视图(react_component),只传递主模型。

我以前经历过这种情况,没有反应前端,它也没有工作。可能有什么不对?

2 个答案:

答案 0 :(得分:1)

问题不在于实例变量中的数据,而在于序列化。

react_component视图助手将在第二个参数上调用to_json方法,如果它不是字符串。在您的情况下:{calendar_items: @calendar_items}.to_json,它以递归方式工作,因此您希望确保@calendar_items.to_json返回预期的JSON输出。您可以使用@calendar_items.serializable_hashrails console中对其进行测试,它会返回一个散列,这对人类来说更具可读性。

或者您将数据序列化为字符串并随身携带react_component

我不知道Rails 5序列化,但它似乎与ActiveModelSerializers类似,因此您可以在序列化输出中包含关系,如:@calendar_items.to_jso(include: [:documents])。在ActiveModelSerializers中,您可以为每个类指定一个序列化程序,并指定它们之间的关系,这些关系可以自动包含在内。

因此,一个有效的解决方案可能是:

def show
  calendar_items = CalendarItem.where(schedule: @schedule).includes(:people, :documents)
  @react_component_props = { calendar_items: calendar_items.to_json(include: [:people, :documents]) }
end

= react_component('CalendarItemsList', @react_component_props)

适度提示:您可以在CalendarItem模型上创建by_schedule范围,以便稍后使用它:CalendarItem.by_schedule @schedule

修改

如果您需要视图中其他位置的数据,则可以使用as_json方法:

def show
  calendar_items_scope = CalendarItem.where(schedule: @schedule).includes(:people, :documents)
  @calendar_items = calendar_items_scope.as_json(include: [:people, :documents])
end

答案 1 :(得分:0)

解决方案 - 解决方法是添加as_json并在其中包含associatiosn:

@calendar_items = CalendarItem.where(schedule: @schedule)
                              .as_json(include: [:people, :documents])

按预期加载/序列化关联。