我在to_builder
模型上定义了Location
方法。这是方法:
class Location < ActiveRecord::Base
def to_builder
Jbuilder.new do |json|
json.(self, :id, :latitude, :longitude, :name, :description)
end
end
end
如果我从数据库中选择Location
,我可以将其转换为JSON,如下所示:
Location.first.to_builder.target!
这很有效。如何为Location
模型集合做同样的事情?例如,如果我通过关系(Area
has_many :locations
)从数据库中获取多个。
locations = Area.first.locations
有没有一种简单的方法可以使用Jbuilder将locations
转换为json?我目前的解决方案是定义一个帮助方法,将模型或集合转换为json。例如:
def json_for(object)
if object.is_a? ActiveRecord::Relation
a = object.map do |o|
o.to_builder.target!
end
"[#{a.join(',')}]".html_safe
else
object.to_builder.target!.html_safe
end
end
然后我会打电话给json_for locations
。但这并不是处理它的正确方法。
更新
我还没有找到一个很好的解决方案。目前我正在使用我编写的帮助器来呈现JSON视图的内容。这是助手的样子:
def json_for(view, locals_hash = {})
render(template: view, formats: [:json], locals: locals_hash).html_safe
end
然后,我在视图中使用这样的帮助器,传入视图中使用的任何变量:
<%= json_for 'locations/index', { locations: @locations } %>
我也有部分帮手:
def json_for_partial(partial, locals_hash = {})
render(partial: partial, formats: [:json], locals: locals_hash).html_safe
end
总而言之,我根本没有使用to_builder
方法。相反,我正在创建实际的jbuilder视图文件,然后使用帮助器在我的应用程序中的任何地方呈现它们生成的JSON。
答案 0 :(得分:0)
您可以将集合呈现为一个利用to_builder覆盖的数组,如下所示:
public class AlarmReceiver extends BroadcastReceiver {
@Override public void onReceive(
final Context context,
final Intent intent) {
// Sanity check on the received intent.
if ((intent == null) || (intent.getAction() == null)) {
Log.v(TAG, "Alarm received but the extra doesn't contain valid informations");
return;
}
if (!validAlarmReceived(alarm)) {
//try to set alarm again, use the same request code to cancel the pending intent
AlarmManager.rescheduleCurrentAlarm(alarm, context);
return;
}
}
}
/**
* Sanity check to see if alarm has been prematurely triggered
* due to odd behavior with PowerSave on some devices.
*/
private boolean validAlarmReceived(
final Alarm alarm) {
if (alarm.isSnoozed()) {
//avoid time check for snoozed alarms
return true;
}
final long alarmMillis = alarm.getCurrentTriggerTime();
final long currentMillis = System.currentTimeMillis();
final long difference = (currentMillis - alarmMillis);
final long THRESHOLD = TimeUnit.MINUTES.toMillis(1);
// Allow the notification to show under the following scenarios:
// 1. The alarm triggered late (i.e. current millis > alarm millis)
// 2. OR the alarm triggered within the threshold value
if (difference > 0 || Math.abs(difference) < THRESHOLD) {
return true;
} else {
// otherwise reschedule the alarm
return false;
}
}
}