2

so i have this controller and i want to add a dynamic attribute along with the other data in the @events instance variable

i have search and tried things like @events.attributes.merge(appointment: true)

appointment = true is what i want to add to the events object.

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

end

ajax code here

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);
      }
    });

so how can i add that property?

Petros Kyriakou
  • 5,214
  • 4
  • 43
  • 82
  • Do you mean you want to add a method/instance variable to the object in memory ? Or you want to also persist this new attribute in the database ? – Cyril Duchon-Doris Aug 16 '15 at 22:31
  • I just want to add that method and render it to the view without storing it anywhere in db so i have access to that method value on success of ajax request. – Petros Kyriakou Aug 16 '15 at 22:32
  • Alright, for JSON/AJAX this become more problematic, because you also have to override the `to_json` to include the new field, not just the object in memory (ie: explicitely tell the serializer to include your new field). Also, you should edit the question title to reflect that. – Cyril Duchon-Doris Aug 16 '15 at 22:46

3 Answers3

4

This could work ? But then maybe the JSON output isn't what you expected ?

format.json { render :json => {events: @events, appointments: true} }
Cyril Duchon-Doris
  • 12,964
  • 9
  • 77
  • 164
  • Sorry it took some time for a simple line of code. Instead of posting an answer for a different question, I ended up editing someone else's answer, and when I noticed, then I had to figure how to rollback my mistake ^^". That'll teach me to close tabs : – Cyril Duchon-Doris Aug 16 '15 at 23:46
2

Because this property is view oriented, the model should not know about it. A better way to do this, is to use a decorator, which will allow you to add what ever attributes you want in the manner you want, without polluting the model. you can create a PORO object like this one

# 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

a better way is to use the draper gem. You can find a good explanation in this railscat, #286 Draper

Nafaa Boutefer
  • 2,169
  • 19
  • 26
0

Two ways to do that I can think of: adding an instance variable or a custom method (or something hybrid)

EDIT : Forget what I said about creating an instance variable out of nowhere (see this answer)^^"

Method

@events.define_singleton_method(:appointments?){true/false}
@events.appointments? # => true/false

EDIT 2 : AJAX/JSON override

See this answer

def @events.as_json(options = { })
    h = super(options)
    h[:appointments]   = true/false # Or combine with above h[:appointments] = self.appointments?
    h
end
Community
  • 1
  • 1
Cyril Duchon-Doris
  • 12,964
  • 9
  • 77
  • 164