Ruby runtime config variables or constants - ruby

I'm giving out a 'n' days free access to users when they sign up. Now I'd like to keep testing this value and would like to give out an interface for the admins so they can try it out without my intervention.
The obvious solution, atleast to me, was to define a new modal with a single field and retrieve the last value from this table.
class TrialTime
include Mongoid::Document
field :trial_time, type: Integer
end
and something like TimeTime.last.trial_time, only this looks inefficient to me.
Somehow I feel that configuration variables would be a better fit here. But I could not figure out how to persist this. Or am I completely over thinking this and the basic DB based solution is the right one?

Related

Can pundit policies be loaded from database?

I like the simplicity of Pundit gem and I would like to make policies dynamic by storing them to database.
Basically I'm looking for a way to be able to change policies without need to redeploy the application.
1st way
Pundit policy is pure ruby code, so if you don't want to keep code inside database and evaluate it dynamically, I'd say the answer is no. It's unsafe. You may give it a go, though.
2nd way
But nothing prevents you from creating model which keeps rules in simple json and compare them using Pundit, e.g.:
class PostPolicy < ApplicationPolicy
def update?
access_setting = PolicySetting.find_by(key: self.class_name)
user.role.in?(access_setting['roles'])
end
end
Of course, complexity and flexibility of the tool directly depends on each other.
3rd way
Is just work around. You may set you authorisation project apart from the main one, so that it's deploys (zero-downtime, of course) would not affect the main big project.
4th way
Create your own DSL to be stored in Database
5th way
Use something like json-logic-ruby to store logic in database

How to get different parameter types per Joomla ACL ?

Right now you can only set 'Allowed', 'Inherited' and 'Prohibited' per Joomla ACL. That's fine but far from complete. Consider the simple case you want to set a string per ACL, like 'allowed upload extensions'. There seems little or no information about.
Any ideas on this ? Its seems even more complicated when you want to register 'dynamic' parameters on the fly, so all this XML based persistence model you have in Joomla will fall a part as well...
Thanks!
This would be wrong, and a nightmare to debug (imagine guiding users when they start calling because they can't do something, and you have no idea where to look).
If you want your component to have more user-configurable actions, you can define some params in the config, where you set the list of extensions allowed in a custom action level, such as "extensions.safe", then assign that. You can create as many as you want. Find more info here
Unless you're proposing that existing components take into consideration arbitrarily defined dynamic parameters, it's hard to see how it could work.

Is it possible to rename fields in django restframework

My python code has fields named like field_name which is fine for python and works well with Django.
Lots of Javascript linters want you to make it fieldName or they whine at you a lot.
Trying to find a nice common ground between the two, I've written serializers like
class MySerializer(serializers.ModelSerializer):
fieldName = serializers.WritableField(source='field_name', required=True)
class Meta:
model = Widget
exclude = ('field_name',)
Problem is that this does NOT replace the external representation of field_name with fieldName, it sends both fieldName and field_name. So I told it to exclude the ('field_name'). Then when you are trying to save, it gets really upset because field_name isn't present, or fieldName isn't a member of the object.
I had thought that mapping would be a good way to do this, but it doesn't appear to be so. Is there someway to map the names from python -> javascript so the code can look pretty on both ends?
Found a package that takes care of it at the json level:
https://pypi.org/project/djangorestframework-camel-case/
Documentation is very sparse, but it appears to work, and integrating it is trivial (which might explain the sparse documentation).
You code should be working. So there's something missing from the example
The thing that comes to mind is your fields value — what do you have specified there? It's generally better to explicitly specify the fields you want there rather than using exclude — it takes longer to set up (maybe) but it'll save time in the long run.
If fieldName is included in fields and field_name is not I would expect your code to work.
(Perhaps show a little more if that doesn't solve it.)
Update after edit to question
Ok. Yes. You should specify the fields you want. Your fieldName is acting as an extra field with its source as field_name — this sort of thing is useful when using SerializerMethodField for example.
Update: Extra Solution
There's a ticket asking about Camel-casing field names for better compatibility with e.g. JavaScript clients. This links to a Gist with a working solution via custom renderer and parser classes.

Philosophy Object/Properties Parameter Query

I'm looking at some code I've written and thinking "should I be passing that object into the method or just some of its properties?".
Let me explain:
This object has about 15 properties - user inputs. I then have about 10 methods that use upto 5 of these inputs. Now, the interface looks a lot cleaner, if each method has 1 parameter - the "user inputs object". But each method does not need all of these properties. I could just pass the properties that each method needs.
The fact I'm asking this question indicates I accept I may be doing things wrong.
Discuss......:)
EDIT: To add calrity:
From a web page a user enters details about their house and garden. Number of doors, number of rooms and other properties of this nature (15 in total).
These details are stored on a "HouseDetails" object as simple integer properties.
An instance of "HouseDetails" is passed into "HouseRequirementsCalculator". This class has 10 private methods like "calculate area of carpet", "caclulateExtensionPotential" etc.
For an example of my query, let's use "CalculateAreaOfCarpet" method.
should I pass the "HouseDetails" object
or should I pass "HouseDetails.MainRoomArea, HouseDetails.KitchenArea, HouseDetails.BathroomArea" etc
Based on my answer above and related to your edit:
a) You should pass the "HouseDetails"
object
Other thoughts:
Thinking more about your question and especially the added detail i'm left wondering why you would not just include those calculation methods as part of your HouseDetails object. After all, they are calculations that are specific to that object only. Why create an interface and another class to manage the calculations separately?
Older text:
Each method should and will know what part of the passed-in object it needs to reference to get its job done. You don't/shouldn't need to enforce this knowledge by creating fine-grained overloads in your interface. The passed-in object is your model and your contract.
Also, imagine how much code will be affected if you add and remove a property from this object. Keep it simple.
Passing individual properties - and different in each case - seems pretty messy. I'd rather pass whole objects.
Mind that you gave not enough insight into your situation. Perhaps try to describe the actual usage of this things? What is this object with 15 properties?, are those "10 methods that use upto 5 of these input" on the same object, or some other one?
After the question been edited
I should definitely go with passing the whole object and do the necessary calculations in the Calculator class.
On the other hand you may find Domain Driven Design an attractive alternative (http://en.wikipedia.org/wiki/Domain-driven_design). With regard to that principles you could add methods from calculator to the HouseDetails class. Domain Driven Design is quite nice style of writing apps, just depends how clean this way is for you.

Ruby, Candy and SQL-like mongo stuff

So Candy is a really simple library for interacting with Mongo in Ruby.
My poor SQL brain is having a tough time figuring out how I should map out this problem:
There are users, there are things. Each thing was made by one user, but should be accessible to a subset of all users (specified within the thing). Leaving the specification of user out of the way for now, how would I get a list of all things that user X has access to?
class Thing
include Candy::Piece
end
class Things
include Candy::Collection
collects :thing
end
Should I assign the allowed users to a thing like this? (lets just use strings to reference users for now)
t = Thing.new
t.allowed = ['X','Y','Z']
This seems about right to me, which would make me want to do:
Things.find(allowed:'X')
but it's not quite working…
NoMethodError: undefined method ‘call’ for {:allowed=>"X"}:Hash
any ideas?
I'm really sorry I took so long to catch this and respond. This might be too late for your purposes, but:
Candy doesn't implement a find method. This is on purpose: if an object represents a collection, every access is implicitly finding something in that collection. It's the same reason there is no save method. If the mapping is truly transparent, verbs that mean "Do this in the database" shouldn't be necessary.
So to do what you want, you could either just make a new Things object with the scope passed on creation:
x_is_allowed = Things.new(allowed: 'X')
...or you could save a step and do it by class method:
x_is_allowed = Things.allowed('X')
...or you could start with the whole collection and limit it by attribute later:
things = Things.new
x_is_allowed = things.allowed('X')
So... Um. All of those will work. But. I have to warn you that I'm really not happy with the general usability of Candy right now, and of collections and array fields in particular. The biggest problem is accessors: the [] method isn't working like you'd expect, so you end up having to call to_a and refresh and other things that feel sticky and unpleasant.
This needs to be fixed, and I will do so as soon as I finish the driver rewrite (a related project called Crunch). In the short term, Candy is probably best viewed as an experiment for the adventurous, and I can't guarantee it'll save time until the interface is locked down a bit better. I'm sorry about that.

Resources