0

I'm debugging a variable from my controller in a view and it's showing me what I expect to see which is an object with properties:

--- !ruby/hash:Parse::Object
alternativeColour: false
collection: 1
colour: 2
favourite: false
gender: 2
image: !ruby/object:Parse::File
  parse_filename: dcefd915-eee7-4203-840b-sdsdsd34refdd-image3.jpg
  url: http://files.parse.com/erre43-7f16-479f-97e6-343434/dcefd-image3.jpg
price: 23.42
productType: 2
recommended: false
size: 6
title: Bomber Jacket
createdAt: '2014-04-03T20:33:41.020Z'
updatedAt: '2014-06-18T19:03:24.220Z'
objectId: yZkfeeNJPm

In my controller I have:

  def edit
      @garment = Parse::Query.new("Garments").eq("objectId", params[:id]).get.first
  end

This takes an objectId of an item that was clicked on on another pages and grabs the matching item from parse.com database so I can edit anything I wish to.

Now my edit page loads fine without my form and when I debug the controller var the first piece of code I copied and pasted above it what comes up. So I know for sure I have a returned object.

I also even tested for a titie by using:

<%= debug @garment["title"] %>

This works fine. So now i wish to add my form then make the values of the textfields and select drop downs reflect what's stored in the database for that particular item. The problem is I get an error that states:

undefined method `title' for #<Parse::Object:0x007fer0h02y5c0>

Here is my form:

<%= form_for :garment, :url => adminpanel_url, :html => {:multipart => true} do |f| %>
  <%= f.text_field :title, :class => "formFields", :placeholder => "Title" %> 
  <%= f.text_field :price, :class => "formFields", :placeholder => "Price" %> 
  <%= f.select :recommended, [["Yes", true], ["No", false]], :include_blank => "Make Recommended?" %>
  <%= f.select :alternativeColour, [["Yes", true], ["No", false]], :include_blank => "Alternative Colour?" %>
  <%= f.select :gender, [["Male", 1], ["Female", 2]], :include_blank => "Select Gender" %>
  <%= f.select :productType, [["T-Shirt", 1], ["Shirt", 2], ["Hoody", 3], ["Gilet", 4], ["Jacket", 5]], :include_blank => "Select Product Type" %>
  <%= f.select :size, [["Size 8", 1], ["Size 10", 2], ["Size 12", 3], ["Size 14", 8], ["Small", 4], ["Medium", 5], ["Large", 6], ["X-Large", 7]], :include_blank => "Select Product Size" %>  
  <%= f.select :colour, [["Black", 1], ["Blue", 2], ["Green", 3], ["Grey", 4], ["Navy", 5]], :include_blank => "Select Product Colour" %>
  <%= f.select :collection, [["Tailor Made", 1], ["Raw & Uncut", 2], ["Custom", 3]], :include_blank => "Select Collecton" %>
  <%= f.file_field :image %> 
  <%= f.file_field :image2 %> 
  <%= f.file_field :image3 %> 
  <%= f.file_field :image4 %>
  <%= f.file_field :image5 %>
  <%= f.file_field :image6 %>
  <%= f.submit "Add Item", :id => "addItemButton" %> <br \>
<% end %>

With the results of my debug above I would have thought my form would work just fine but it doesn't and I'm getting this error:

undefined method `title' for #<Parse::Object:0x007fff0fedd1e0>

What could the issue be? I've done some googling and looked at the server logs but can't seem to find what is wrong. As soon as I remove the form and just leave the debug line in the error is gone. So the error is definitely being caused my form.

This is my model just incase you're wondering:

class Garment
    include ActiveAttr::Model
    #include ActiveModel::Validations
    extend CarrierWave::Mount

    attribute :alternativeColour
    attribute :title
    attribute :image
    attribute :image2
    attribute :image3
    attribute :image4
    attribute :image5
    attribute :image6
    attribute :price
    attribute :recommended
    attribute :gender
    attribute :productType
    attribute :size
    attribute :colour 
    attribute :collection

    mount_uploader :image, ImageUploader

Help will be much appreciate.

Thanks for your time.

LondonGuy
  • 10,778
  • 11
  • 79
  • 151
  • `<%= debug @garment["title"] %>` You aren't calling a method here, you are calling the key for a hash. Are you sure that's not your problem? You're getting a hash back in your `garment` variable, not an object, and rails form_helpers are trying to call object methods. -- Or it may not be an actual hash, but it's an object that acts like one. Does calling `@garment.title` work? Or can you only get it with `@garment['title']`? – nzifnab Aug 06 '14 at 23:11
  • But this is how I call object properties from parse.com. Look here https://github.com/adelevie/parse-ruby-client there is no other way for me to read the object porperties. – LondonGuy Aug 06 '14 at 23:16
  • The error is coming from the form. Even when I remove the debug code the error is still present. – LondonGuy Aug 06 '14 at 23:17
  • At what point does a `Parse::Query` instantiate a `Garment` class? Your error mentions `#`, but not the actual `Garment` class you have defined, is that class being used? – nzifnab Aug 06 '14 at 23:21
  • @nzifnab I'm using a database from parse.com and not the one defined. Basically this is a tableless app. Not using Active Record. – LondonGuy Aug 06 '14 at 23:33
  • I recognize you aren't using active_record, but that doesn't mean you're not still dealing with ruby classes and objects ;) You can instantiate a garment class yourself if you want to use that class. – nzifnab Aug 06 '14 at 23:35

2 Answers2

2

Before doing my original answer... try changing your controller code to instantiate your garment class:

  def edit
      @garment = Garment.new Parse::Query.new("Garments").eq("objectId", params[:id]).get.first
  end

I looked at the active_attr code and it looks like this will work if that Parse::Query is returning a hash (which it seems like it is).

Old Answer

Try adding this to your Garment class definition:

def method_missing(method_name, *args)
  if self[method_name.to_s].present?
    self[method_name.to_s]
  else
    super
  end
end

You'll have to append to this to make setters work correctly.

This assumes that your Parse::Query call is at some point instantiating a Garment class. Where does that happen?

nzifnab
  • 15,876
  • 3
  • 50
  • 65
  • I thought that's what was happening in the edit action. After all I do get an object returned. – LondonGuy Aug 06 '14 at 23:28
  • How do I use the code above. Do I paste in my model as is? – LondonGuy Aug 06 '14 at 23:30
  • Well I don't know, your object dumps are saying they are `Parse::Object` classes, not `Garment` classes. Do you need to name your class `Parse::Garment`? Or instantiate it manually or something? I'm not sure this code will work until you're actually dealing with a `Garment` class. (For instance, if you call `Rails.logger.debug(@garment.class.to_s)` I suspect it won't say `Garment` or antying). – nzifnab Aug 06 '14 at 23:34
  • @LondonGuy I've updated my answer, try just instantiating the `Garment` class manually like I've mentioned and see if it then has access to things like `@garment.title`. If that works, you don't need to add the method_missing that I had in here first. – nzifnab Aug 06 '14 at 23:41
0

Change :garment to the actual object, ie

<%= form_for @garment, :url => adminpanel_url, :html => {:multipart => true} do |f| %>
ob264
  • 535
  • 2
  • 6
  • 1
    `form_form @garment` and `form_for :garment` are *the exact same thing* if you have an instance variable named `@garment` available. If you use the symbol, it looks for an instance variable of that name. – nzifnab Aug 06 '14 at 23:12
  • First thing I tried but gave me a undefined method model_name – LondonGuy Aug 06 '14 at 23:14
  • @LondonGuy for that error you can add `extend ActiveModel::Naming` to your object's definition – nzifnab Aug 06 '14 at 23:16