Associations / json and doing things right

I’m doing stuff with Apps in the App Store. Apps belong to a price tier.
Such that.

App
belongs_to :tier

Tier
has_many :apps

All good so far.

I want to monitor when an app changes tier amongst other thing, don’t
need a history, but need to record the previous tier.

My plan was to store attributes on the App for tier_code and
previous_tier_code, but this strikes me as wrong because an App belongs
to a Tier at a point in time so I don’t need to store the tier code
twice (and I shouldn’t).

The main reason I’ve stuck the tier_code attribute on the App is I wish
to serve up JSON from the AppController’s index action. With all the
attributes I need on the App directly I can just format.json { render
:json => @apps } or the like.

What could/should I do, ideally I’d like to remove the tier_code
attribute on the App, and incorporate it in the json via the association
<- looked into this and it made my head spin.

bingo bob wrote in post #969776:

I’m doing stuff with Apps in the App Store. Apps belong to a price tier.
Such that.

App
belongs_to :tier

Tier
has_many :apps

All good so far.

I want to monitor when an app changes tier amongst other thing, don’t
need a history, but need to record the previous tier.

Then you probably want one of the version plugins such as
vestal_versions.

[…]

The main reason I’ve stuck the tier_code attribute on the App is I wish
to serve up JSON from the AppController’s index action. With all the
attributes I need on the App directly I can just format.json { render
:json => @apps } or the like.

The tier_code definitely belongs on the App – it’s a property of the
App, after all. You should have no misgivings about putting it there.

What could/should I do, ideally I’d like to remove the tier_code
attribute on the App, and incorporate it in the json via the association
← looked into this and it made my head spin.

Uh, what? You’ve already got it there as an association. What do you
think you want to do differently? And what “made your head spin” –
that is, what didn’t you understand? Statements such as this are
completely unhelpful without more detail.

Or are you saying that App has both a tier_id and a tier_code ? If so,
then you’re right; that’s terrible.

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

Sent from my iPhone

Or are you saying that App has both a tier_id and a tier_code ? If so,
then you’re right; that’s terrible.

oops - yes, that’s what I’d doing at the moment - and I’d like to change
that I realise it’s terrible. The question I have is if I remove the
tier_code then how do I serve up json from my index action in the
controller together with the apps “associated” tier_code.

bingo bob wrote in post #969803:

Or are you saying that App has both a tier_id and a tier_code ? If so,
then you’re right; that’s terrible.

oops - yes, that’s what I’d doing at the moment - and I’d like to change
that I realise it’s terrible. The question I have is if I remove the
tier_code then how do I serve up json from my index action in the
controller together with the apps “associated” tier_code.

Go read the docs for to_json ; this is explained clearly. Pay special
attention to the :include option.

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

Sent from my iPhone

On Dec 27, 2010, at 7:38 AM, bingo bob wrote:

Not sure it’s what I want though - will it allow me to do stuff like
App.versionnumber.attribute?

I’ve been using it for two different projects now. It’s very smooth.
All you need to do is put the versioned command in your model, and
build your VV table with a rake task, migrate, and you’re set. The
versions are saved in YAML format in one big text field in the VV
table, so there’s no need to have custom VV tables based on your
model, it just works. Once you have set up VV, you can add it to
another model with no further changes by simply adding versioned to
that model.

If there is a difference in regular (table-backed) attributes from one
version of an object to another, then yes, getting a specific version
will give you the complete state of the object as of that version.
There’s nothing extra you need to do in order to get that, it just
works.

But if you want to have related (has_many) attributes and get the
value of those as of a particular version of the parent, then you will
need to find another solution. There’s no way to do that with VV as
far as I know.

I also had to do some hacking to Paperclip in order to have versioned
attached photos. It’s very messy and monkey-like, but if you’d like to
see it, let me know.

Walter

Have started to look at vestal versions…appears that it might be just
the ticket, thanks for the idea.

To use it, I imagine I have to specify any attributes I wish to version
in the migration file generated by the vestal versions generate script -
that right ?

Not sure it’s what I want though - will it allow me to do stuff like
App.versionnumber.attribute?

bb

Thanks Walter, very clear and useful, it looks right for me - but two
things.

  1. Why does it create the user stuff in the vv migration/model - I dont
    have users in this app, should I delete those attributes or just not
    worry about them, and it’ll just work ™.

  2. It seems to be more aimed at REVERTING to previous versions rather
    than querying them - to explain, in my app I’d like to keep a history of
    price tiers of apple store apps, so each day an App.tier might equal a
    different value, I might like to print them all out over time or chart
    them or more likely find an apps highest or lowest tier historically -
    is that easy/doable with VV?

It looks very powerful.

Thanks

bb

On Dec 28, 2010, at 4:45 AM, Colin L. wrote:

  1. Why does it create the user stuff in the vv migration/model - I
    dont
    have users in this app, should I delete those attributes or just not
    worry about them, and it’ll just work ™.

The user stuff relates to which user made these changes, nothing else.
VV can do multi-user edits and tracks which user made each edit. Very
powerful stuff, but I haven’t used that feature yet.

is that easy/doable with VV?

If what you want to do is store a set of values for something varying
over time and wish to query the set, pick out max and min and so on
then I suggest this is not best served by versioning. Instead model
it in the normal way. So App has_many price_tiers, PriceTier
belongs_to app, and a PriceTier has a date field you can query on.

Colin

I concur. All I have ever used it for is reverting. I can only query
the current model, since the pickled objects in the VV table aren’t
much good for that (barring raw text matching). I make a little
“pager” control in the edit view and step through the available
versions, the user can pick one and decide to revert to it by saving
the object while it is reverted to that particular state (creating a
new max+1 version that is a copy of version N).

Walter

If what you want to do is store a set of values for something varying
over time and wish to query the set, pick out max and min and so on
then I suggest this is not best served by versioning. Instead model
it in the normal way. So App has_many price_tiers, PriceTier
belongs_to app, and a PriceTier has a date field you can query on.

Colin

Thanks Colin, realised this is the way to go.
Unless I’m mistaken I can just use the created_at date field to query
on?

On 28 December 2010 06:32, bingo bob [email protected] wrote:

different value, I might like to print them all out over time or chart
them or more likely find an apps highest or lowest tier historically -
is that easy/doable with VV?

If what you want to do is store a set of values for something varying
over time and wish to query the set, pick out max and min and so on
then I suggest this is not best served by versioning. Instead model
it in the normal way. So App has_many price_tiers, PriceTier
belongs_to app, and a PriceTier has a date field you can query on.

Colin

On 2 January 2011 14:29, bingo bob [email protected] wrote:

on?
If created_at suits your need then certainly.

Colin