Ruby on rails 如何修改to_json方法并向其添加动态属性-Rails 4

Ruby on rails 如何修改to_json方法并向其添加动态属性-Rails 4,ruby-on-rails,ruby,ajax,json,ruby-on-rails-4,Ruby On Rails,Ruby,Ajax,Json,Ruby On Rails 4,所以我有这个控制器,我想在@events实例变量中添加一个动态属性和其他数据 我搜索并尝试了类似@events.attributes.merge(约会:true) appointment=true是我要添加到events对象的内容 def find params = event_params current_user = 2 @events = Event.where('date LIKE ?',"%#{params[:month]}%") def @events.as_json(optio

所以我有这个控制器,我想在@events实例变量中添加一个动态属性和其他数据

我搜索并尝试了类似@events.attributes.merge(约会:true)

appointment=true是我要添加到events对象的内容

def find
params = event_params

current_user = 2
@events = Event.where('date LIKE ?',"%#{params[:month]}%")

def @events.as_json(options = { })
    h = super(options)
    h[:appointments]   = false # Or combine with above h[:appointments] = self.appointments?
    h
end

respond_to do |format|
  if current_user == 1

    if @events

      format.json {
        render json: @events.to_json
      }
    else
      render 'index'
    end
  else

    format.json {
      render json: @events.to_json
    }
  end
end
结束

此处的ajax代码

function retrieve(date_partial) {

    var jsondata = {
      events: {
        month: date_partial,
      }
    }

    $.ajax({
      cache: false,
      type: "POST",
      url: "/events/find",
      data: jsondata,
      success: function(data) {
        console.log(data);
        for (var i = 0; i < data.length; i++) {
          var day = data[i].date.substring(0, 2);
          $("td[data-day='" + day + "']").addClass('added');
        }

      },
      error: function(xhr) {
        alert("The error code is: " + xhr.statusText);
      }
    });
函数检索(日期部分){
var jsondata={
活动:{
月份:日期,
}
}
$.ajax({
cache:false,
类型:“POST”,
url:“/events/find”,
资料来源:jsondata,
成功:功能(数据){
控制台日志(数据);
对于(变量i=0;i

那么如何添加该属性呢?

我可以想到两种方法:添加实例变量或自定义方法(或混合方法)

编辑:忘了我说过的关于无处创建实例变量的内容()^”

方法

@events.define_singleton_method(:appointments?){true/false}
@events.appointments? # => true/false
编辑2:AJAX/JSON覆盖


因为此属性是面向视图的,所以模型不应该知道它。更好的方法是使用装饰器,这将允许您以所需的方式添加所需的任何属性,而不会污染模型。 可以创建PORO对象 像这个

# this is by no means a complete implementation, but just for you
# to get the idea
class EventDecorator
  # use ( delegate :event_attribute, to: :event ) to delegate 
  # all the event attributes and to be able to access them
  # as if they were declared on the decorator itself
  attr_reader :event
  attr_accessor :appointment
  def initialize(event)
    @event = event
    @appointment = false
  end

  def to_json
     event.attributes.merge(appointment: appointment).to_json
  end
end

更好的方法是使用gem。你可以在这个railscat中找到一个很好的解释,

这可以工作吗?但是也许JSON输出不是你所期望的

format.json { render :json => {events: @events, appointments: true} }

你的意思是想向内存中的对象添加一个方法/实例变量?还是想在数据库中持久化这个新属性?我只想添加该方法并将其呈现到视图中,而不将其存储在db中的任何位置,这样我就可以在ajax请求成功时访问该方法值。好吧,对于JSON/ajax来说,这将成为一个更大的问题tic,因为您还必须重写
to_json
以包含新字段,而不仅仅是内存中的对象(即:明确地告诉序列化程序包含您的新字段)。此外,您还应该编辑问题标题以反映这一点。我尝试了您的第一个方法(实例变量),我为anyname得到了这个结果('appointment'不允许作为实例变量名)使用第二个方法,我没有收到任何错误,但我在ajax请求的返回数据中看不到它……如果您真的还想序列化/ajax,问题就更难了。您能编辑您的问题以添加相关的视图代码吗?我现在已经添加了它!)嗯,我看到了你的新代码,但我想通过ajax成功回调将events.appointment值传递给视图,我想你给我的是rails控制器?听起来不错,但你也应该展示如何在OP的上下文中使用它。该死的,我不知道如何实现;o-EDIT:Cyril说了什么;p看看这里以了解什么是装饰师以及如何使用装饰师。好吧,花点时间阅读德雷珀自述,这是值得学习的。它不是很复杂,一旦你理解了它,你的代码将更加有条理和干净。很抱歉,花了一些时间来编写一行简单的代码。我没有发布不同问题的答案,而是编辑了其他人的答案回答,当我注意到时,我必须想一想如何回滚我的错误^^”。这将教会我如何关闭选项卡:
format.json { render :json => {events: @events, appointments: true} }