Rhomobile model error - Undefined method

Greetings,

I get the error undefined method 'find' for Auth:Class on this code:

class Auth

  include Rhom::FixedSchema

  set :schema_version, '0.1'

  property :field1, :string

  property :field2, :string

  def self.auth_record

    @auth_record ||= begin

      if find(:count) == 0 # This is the line raising the error

        create

      else

        find :first

      end

    end

  end

end

Also when inspecting Auth.ancestors I got this output [Auth, Rhom::FixedSchema, Rhom::BaseModel, Object, JSON::Pure::Generator::GeneratorMethods::Object, Kernel, BasicObject]

I did follow the doc strictly, and cannot find any info on google. Any help greatly appreciated

Kutir Mobility
Hi Benj,What version of

Hi Benj,

What version of RhoMobile you use and at what point you get this error?

Visnupriya R
Kutir Mobility

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Benj Bouch
Hi Kutir, and thanks for your

Hi Kutir, and thanks for your reply

Rhodes v 4.1.1

It's actually a new application, the beginning of a project but I'm still at trying to understand the internals of Rhodes.

So I created this Auth class (for which you can find the code in my original message) And I am trying to use it through the controllers. So to answer your question: it's at the start of the app.

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Jon Tara
What the heck is this?! 

What the heck is this?!

  @auth_record ||= begin


And what are you trying to do here?


  if find(:count) == 0


I think it's too soon to try to use the database at that point - it hasn't been created yet!





Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Benj Bouch
Basic ruby caching technique:

Basic ruby caching technique: first time method is call it executes the block and cache the result in the instance variable. Next calls the block is not executed and value in the instance variable directly returned.

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Benj Bouch
TAble not created yet? Can

TAble not created yet? Can you elaborate, it seems to be the reason of my problem. Thanks

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Benj Bouch
Many thanks "Jon Tara" for

Many thanks "Jon Tara" for being that helpful. This community is weak and by that I mean poor information available on internet, the documentation is mostly not a good help. But thanks to your answer everything becomes suddenly clear...

Let me give you an advise: when you don't know something be humble and do not use rude words such as "What the heck" or abusive punctuation like "?!". You cannot know everything. I have been developing on dozen on languages and frameworks since 1990 and I do not know everything. So take example and be humble. For the sake of the community.

Yes I am a newcomer to Rhodes, and I don't know how to create a table for a local non-sync model. Your reply "it hasn't been created yet!" is too short to be helpful or too long for not being rude. So would you be kind enough to elaborate so I can continue discovering this great framework.

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Hector Meza
Benj, models (data tables)

Benj, models (data tables) can be created in a number of ways.  The most common approach is to create the model when you create your project via the RhoStudio  (New, RhoMobile Model) - this will create the base scaffolding that can be used or replaced with your own code.  The other approach would be to create the models dynamically within your application via the ORM API - Rhomobile | [Your-OrmModel].  I prefer creating a model with the project as it keeps things cleaner but there are time that a dynamic creation is needed.

Creating a model with the project will not force you to use RhoConnect (default is to have the sync disabled).

You may want to take a look at the kitchen sink sample application - it has some examples of creating and using the model via the ORM and JavaScript.  - Rhomobile | RhoMobile Suite KitchenSink  the full project is downloaded from Git and is a good resource for many of the API's

Hopefully this points you into the right direction.

HM

Vote: 
Vote up!
Vote down!

Points: 1

You voted ‘up’


Benj Bouch
Hi Hector, and many thanks

Hi Hector, and many thanks for your reply.

Ok understood, and yes I am creating scaffolding files through the rhodes command-line generator (I am on linux, therefore not using RhoStudio). If I understand correctly after checking on the KitchenSink app I must manually create the table with those 2 steps:

  • Open database with Rho::Database.new(Rho::Application.databaseFilePath("my_db"),"my_db")
  • Create the table with SQL query with db.executeSql("Create table ...")

Would you confirm this?


Thanks in advance

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Hector Meza
From your original example it

From your original example it looks like you want to create it in the controller via Ruby – take a look at the ruby example for the Rhom – “New”

http://docs.rhomobile.com/en/4.1.0/api/rhom-api

@account = Account.new(

{"name" => "ABC Inc.","address" => "555 5th St."}

)

@account.name

#=> "ABC Inc."

HM

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Benj Bouch
Tried this, and am back to my

Tried this, and am back to my original problem:

Without changing anything from my original posted example, in my controller action:

> record = Auth.new({'field1' => 'test1', 'field2' => 'test2'})

> record.save

=> undefined method `save' for #<Auth:0xa805d090>

Second try:

> Auth.create({'field1' => 'test1', 'field12' => 'test2'})

=> undefined method `create' for Auth:Class

Third try:

> db = Rho::Database.new(Rho::Application.databaseFilePath('sample'), 'sample')

> db.executeSql('Drop table if exists auth')

> db.executeSql('Create table auth (test1 string, test2 string)')

> db.close

>

> Auth.create({'test1' => 'test1', 'test2' => 'test2'})

=> undefined method `create' for Auth:Class

Any idea? I am missing an include or a declaration somewhere, cause my class Auth seems not to be recognized as a model

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Jon Tara
Sorry, I looked at that line

Sorry, I looked at that line and saw 'begin' which is a Ruby reserved word. Then I saw that extra `end` and assumed you somehow meant to create a begin block but the syntax didn't look right...

So now I have no idea what you have, because it is a tiny bit of code pulled out of context, you are a variable "begin" somewhere which you haven't shown. And apparently something goes with that extra 'end'...

With all that going on, I actually didn't notice your function definition. So, I thought the code inside the function was actually in the class definition and therefore on first use the database would not have actually been created (at least not with a full schema) yet.

Now, where do you actually call auth_record?

Where is 'begin' defined?

Realize: @auth_record is a class instance variable. Is that intentional?

Pretty sure 'begin' is your problem. It's a reserved word in Ruby. It should not be used as a variable name!

Sorry, when I saw that line, I did not see "or equal" which, yes, I use all the time. I saw the 'begin' keyword and what looked like a set of mis-placed block parameter brackets, and a stray '='... It didn't make sense and my thought was... exactly... "what the heck is that?!" Add an extra 'end', and that sealed the deal. He's trying to create some kind of block...

That's what I saw. I can't tell you exactly what Ruby saw. But it's almost certainly not what you'd intended.

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Benj Bouch
For your understanding

For your understanding

def my_method

  @instance_var ||= begin

    perform_something_long_and_expensive

    on_several lines_of: 'code'

  end

end

The code inside the begin/end block will be called once, its result stored in `@instance_var`, and next calls the cached result will be returned from `@instance_var` without calling what's inside the begin/end block

The `begin` goes with the following `end`, there is no extra `end`, it's the delimitation of the block. You can use object instance or class instance vars at your convenience (but mind thread safety)

Note that is you have only one line of code you could get rid of the begin/end syntax:

def my_method

  @instance_var ||= perform_something_long_and_expensive

end

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Benj Bouch
Thanks for coming back on

Thanks for coming back on this.

Ok look let's forget about this part of the syntax. It's not the source of the issue here. I use that coding style permanently and it's very efficient, don't worry about it.

So let's consider I removed this method and I'm left with the class declaration, its include and its properties.

Let's simplify thinks like this:

In my controller's index action when I call

Auth.create 'field1' => 'value1'

It raises "undefined method 'create' for Auth:: class"

Obviously Auth is not recognized as a model object. I'm missing something right? An include or something.

I was searching and trying things for the past 2 days and could not ind anything relevant.

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Jon Tara
Trying adding:  require

Trying adding:

  require_source 'Auth'

at the top of auth.rb.

You aren't giving us much to go on. Most of what little code you posted you told us to "forget about".

Is it a very large, complicated model? Can you just post the whole thing here? Otherwise, can you cut it down, or start with a fresh app and add stuff till it breaks?

No errors in the log?

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Benj Bouch
My mistake was to have

My mistake was to have

require 'Auth/auth'

On top of one of my files.

The framework relies on const_missing to load and initialize the model (inject dependencies, create tables, ...). As I explicitly required the source file, the constant was already defined therefore Rhodes internal did not perform the needed initialization. Removing the `require` fixed the problem.

Lesson learned, also I would says that 1) this is not really solid coding and 2) this is completely undocumented.

Thanks to those who provided me with help.

Regards

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Jon Tara
Ah!Yes, you do not need to

Ah!

Yes, you do not need to/should not require model files!

In fact, we've abused this and written models that have no data in Rhom, just because models are so convenient to use...

require_source is useful in some situations where you need to access one properties of a model without actually calling any method of the model. It's a catch-22 and require_source gets you out of it. It's also useful if you want to force a model (or, typically, all models) to load at startup.

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Log in to post comments