voltrb / volt

A Ruby web framework where your Ruby runs on both server and client
MIT License
3.22k stars 196 forks source link

`config.try` doesn't work in the server? #340

Open myknbani opened 8 years ago

myknbani commented 8 years ago

I tried creating a user in rspec, using the username for the login_field.

I have this line in config/app.rb config.public.auth.use_username = true

This code in user.rb

class User < Volt::User
  # login_field is set to :email by default and can be changed to :username

  puts '-----------------------------------'
  puts Volt.config.try(:public).try(:auth).try(:use_username)
  puts self.login_field
  puts '-----------------------------------'

produces nil and email on the server and RSpec

$ volt console
Volt 0.9.6
-----------------------------------

email
-----------------------------------

while in the browser console, it produces

-----------------------------------
true
username
-----------------------------------

Also, try is added to the Object class, but Volt.config seems to be a BasicObject

[52] volt(main)> Volt.config.is_a? BasicObject
=> true
[53] volt(main)> Volt.config.is_a? Object
=> false
ryanstout commented 8 years ago

This is a known issue with the configuration gem we use to configure stuff with. If anyone wants to head up getting a fix for this let me know. Otherwise, I'll try and get to it soon (since I've hit this a few times myself)

myknbani commented 8 years ago

Thanks Ryan! ^_^

afaur commented 8 years ago

Hello @myknbani

Volt uses the configurations gem to access the configs that you set up.

I tested locally and was able to access the value by using Volt.configuration.public.auth.use_username

Note: You will not however be able to use .try(:symbol) to fetch values.

Reason: The type that your interacting with is a #<Configurations::ArbitraryConfiguration>

Possible Solution: Inspect the value of the first key (in your example that would be public) some pseudocode might look like: if Volt.configuration.public is nil then

There might be some better solutions that you could come up with but at least you could poke at it in the volt console to see what you could do for your specific use case.

-> % bundle exec volt console
Volt 0.9.3
true
[1] volt(main)> Volt.configuration.try(:public).try(:auth).try(:use_username)
=> nil
[2] volt(main)> Volt.configuration.public.auth.use_username
=> true
diff --git a/app/main/models/user.rb b/app/main/models/user.rb
index 05d2ac0..61707dc 100644
--- a/app/main/models/user.rb
+++ b/app/main/models/user.rb
@@ -1,4 +1,10 @@
 # By default Volt generates this User model which inherits from Volt::User,
 # you can rename this if you want.
 class User < Volt::User
+  # login_field is set to :email by default and can be changed to :username
+
+  puts '-----------------------------------'
+  puts Volt.configuration.public.auth.use_username
+  puts self.login_field
+  puts '-----------------------------------'
 end
diff --git a/config/app.rb b/config/app.rb
index ded1a58..f9c8a25 100644
--- a/config/app.rb
+++ b/config/app.rb
@@ -2,6 +2,9 @@
 # then any config options in config.public are passed to the client as well.

 Volt.configure do |config|
+
+  config.public.auth.use_username = true
+
   # Setup your global app config here.

   #######################################

More information about the configurations gem can be found here: https://github.com/beatrichartz/configurations#first-way-arbitrary-configuration

Here is where the volt framework requires it: https://github.com/voltrb/volt/blob/master/lib/volt/config.rb#L44

myknbani commented 8 years ago

@afaur

Yes not using try would work, however it is used by the Volt::User class to give Volt devs the option of using either username or email. Also, the try code produces different results in MRI and Opal.

Not using try also produces different results:

Opal

volt> Volt.config.public.auth.use_username
=> true
volt> Volt.config.public
=> #<OpenStruct: datastore_name="mongo" auth=#<OpenStruct: use_username=true>>

MRI

[7] volt(main)> Volt.config.public.auth.use_username
=> true
[8] volt(main)> Volt.config.public
=> Kernel
[9] volt(main)> Volt.config.public.nil?
=> nil

I think the deeper issue here is that public configs in Volt are meant to be isomorphic.