Is there a better way to do this than using a query string in rails 3? - ruby-on-rails-3

I have two models, we'll call them Entry and Comments for our example, that are associated as Entry has_many :comments and Comment belongs_to Entry. When a new comment is created, I need to obviously supply the id of the Entry for the foreign key. Right now, I'm using a query string. It works like this. A user views and entry, clicks a link to create a new comment (the link looks something like b/new?a_id=1) and then I use the build method to create the new record.
I know if I nested the resources it'd work just fine, but there are reasons that I don't want to do that, namely that I plan to nest a resource under Comments and don't want to go so many levels deep.
I initially had the form for a new comment on the Entry show page, but was having problems doing some custom validations and passing the error messages, etc. (namely, I needed to count the words before submitting).
Any thoughts? I'm not opposed to using query strings, just not sure if there's a better way.

I honestly can't see the problem with nested resources. You're going to have to identify the Entry in your case so your choices are POST /entries/123/comments or POST /comments?entry_id=123. Personally I prefer the former.

Related

Querying an implicit re-orderable list

I was searching for a way to re-order my records, like blog posts, for instance.
One of the solutions I have found is to self-reference to refer to the previous (or next) value, like in a linked list (https://softwareengineering.stackexchange.com/a/375246). However, this requires the client-side (a web service or perhaps a mobile app) to implement the linked-list travesal logic to derive the order.
Is there a way to do this at the database level?
The reason for this is that if you are deriving the order at the client-side, then if you want to display only the first 10 records, you would have to retrieve all the records anyway.
EDIT
It seems the blog posts example was a very bad example, sorry. I was thinking of blog posts as they are displayed on an admin dashboard, and the user can re-order the position they are displayed by dragging and dropping. Hope this is more clear.
EDIT 2
I guess, generally, what I'm really asking is, how can one implement and query a tree-like structure in SQL

How do I batch update my app database?

New to MVC and RoR and having a hard time grasping some of the concepts. One of them is batch updates to the database.
Lets say I have a set of data such as a list of students and their attributes like this
Student ID:1
Name: Alice
email:alice#alice.com
attribute: anything
attribute2: anything2
Student ID:2
Name: Kate
email:kate#kate.com
attribute: anything
attribute2: anything2
etc..
I've gotten the list from an API call.
I don't want them to be editable, nor do I want the attributes to be visible to the user.
Question is, how do I go about saving them into my database? It seems in the MVC way, each action requires a view? Will I be able to do it as a background process?
Thanks
Ryan
p/s- pointers to the right resources welcome too
So you'd just like to obtain records from an API and create models from them?
One option you may consider is writing rake tasks to get the data, and create the corresponding models (No rails answer is complete without a railscast link, so here's one It's old, but tells the basics)
Going this route, you could avoid making the data publicly editable, and just get it into the models/DB
You could use fixtures for this type of thing. Or, just use SQL to insert into your DB outside of Rails.
http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html

Rails save record draft with dummy variable

So I need more alongs the lines of just advice than actual code here, but this is my situation:
I have a model that requires two associations - an author and a user. However, I want it to be possible for authors to create the record with the possibility that it will later be "claimed" by a user created later.
The best solution that I've come up with is to user some sort of "Dummy User" association for those cases, but it feels hacky.
Any better suggestions?
How about making the associations not required? Are the associations enforced with validations? How about relaxing the validations instead? So there would be no user association persisted until the time it is claimed.

Independent Indexes in Elastic Search

UPDATE: Redefined what I am trying to do.
I have a model of Contact, this contact belongs to an account as does every other model in my account. I need all searches whether they be global or model specific to only query the containing account. I was told that I could do this with custom index names. I would like the index name to be the 'index-#{account-id}'. How would I achieve this in my active-models?
class Contact < ActiveRecord::Base
include Tire::Model::Search
include Tire::Model::Callbacks
belongs_to :account
mapping do
indexes :first_name
indexed :last_name
end
end
class Account < ActiveRecord::Base
has_many :contacts
end
You may want to check this comment at Tire's issues, which basically walks through some possible scenarios of the “tenant-based” index naming with Tire. I believe it's what you're after.
In elasticsearch itself, you have the option to have a separate index for every account, a filtered & routed index alias for every account, index templates, etc etc., so the toolkit is vast in this area.
Do you refer to having each account (user?) physically separate in each it's own index? This is generally referred to as 'multi-tenant' http://en.wikipedia.org/wiki/Multitenancy
Assuming this is indeed what you set out to do:
Much has been said in the past about the 'need' (I assume you want this for security reasons, I'm not familiar with other reasons why you would want this although I'm not an expert with multi-tenancy apps) for partitioning data per account/user, as apposed to just having, say, a field accountid for Contact and be sure all your queries filter, at least, on accountid. IMO, a carefully designed query-component where, say, every query used in the system inherits from a 'super-query' which is required to set accountid would suffice in a lot of cases.
Even if you don't know upfront what apps in the future will want to query these indices, you could still enforce the above by say, having a thin REST-service around ES and require all programs to interact with ES through this service. You could then have this service handle this type of security by enforcing an accountid or, probably better, by inferring the accountid by the current logged-in user doing the request.
If you still want to pursue Multi-tenancy have a look at: http://elasticsearch-users.115913.n3.nabble.com/Multi-tenacy-td471400.html (quickly searched this, perhaps there's better stuff around) 'Kimchy' (the creator of ES) comments in that thread as well.
Regardless, the best way in ES to have multi-tenancy is probably to have 1 index per account/user . Within that you could have multiple 'types' (an ES construct) , where Contact could be such a type.
http://www.elasticsearch.org/guide/reference/mapping/
http://www.elasticsearch.org/guide/reference/api/search/indices-types.html
Enforcing this in your models, as you are suggesting, is probably not the correct way IMO. Generally, you should keep your domain-models clean from any knowledge on the storage backend (including the index in which the data is stored)
To me, a better solution would be to have, as earlier suggested, a query-component in which the logic of choosing the correct index based on account/user would be contained. Going with the rest-service approach above, the dynamic indexname, as you suggested, could be derived from the logged-in user doing the request.
I realize that this probably wasn't a straight answer to your question, but I hope it was useful nonetheless.

The REST-way to check/uncheck like/unlike favorite/unfavorite a resource

Currently I am developing an API and within that API I want the signed in users to be able to like/unlike or favorite/unfavorite two resources.
My "Like" model (it's a Ruby on Rails 3 application) is polymorphic and belongs to two different resources:
/api/v1/resource-a/:id/likes
and
/api/v1/resource-a/:resource_a_id/resource-b/:id/likes
The thing is: I am in doubt what way to choose to make my resources as RESTful as possible. I already tried the next two ways to implement like/unlike structure in my URL's:
Case A: (like/unlike being the member of the "resource")
PUT /api/v1/resource/:id/like maps to Api::V1::ResourceController#like
PUT /api/v1/resource/:id/unlike maps to Api::V1::ResourceController#unlike
and case B: ("likes" is a resource on it's own)
POST /api/v1/resource/:id/likes maps to Api::V1::LikesController#create
DELETE /api/v1/resource/:id/likes maps to Api::V1::LikesController#destroy
In both cases I already have a user session, so I don't have to mention the id of the corresponding "like"-record when deleting/"unliking".
I would like to know how you guys have implemented such cases!
Update April 15th, 2011: With "session" I mean HTTP Basic Authentication header being sent with each request and providing encrypted username:password combination.
I think the fact that you're maintaining application state on the server (user session that contains the user id) is one of the problems here. It's making this a lot more difficult than it needs to be and it's breaking a REST's statelessness constraint.
In Case A, you've given URIs to operations, which again is not RESTful. URIs identify resources and state transitions should be performed using a uniform interface that is common to all resources. I think Case B is a lot better in this respect.
So, with these two things in mind, I'd propose something like:
PUT /api/v1/resource/:id/likes/:userid
DELETE /api/v1/resource/:id/likes/:userid
We also have the added benefit that a user can only register one 'Like' (they can repeat that 'Like' as many times as they like, and since the PUT is idempotent it has the same result no matter how many times it's performed). DELETE is also idempotent, so if an 'Unlike' operation is repeated many times for some reason then the system remains in a consistent state. Of course you can implement POST in this way, but if we use PUT and DELETE we can see that the rules associated with these verbs seem to fit our use-case really well.
I can also imagine another useful request:
GET /api/v1/resource/:id/likes/:userid
That would return details of a 'Like', such as the date it was made or the ordinal (i.e. 'This was the 50th like!').
case B is better, and here have a good sample from GitHub API.
Star a repo
PUT /user/starred/:owner/:repo
Unstar a repo
DELETE /user/starred/:owner/:repo
You are in effect defining a "like" resource, a fact that a user resource likes some other resource in your system. So in REST, you'll need to pick a resource name scheme that uniquely identifies this fact. I'd suggest (using songs as the example):
/like/user/{user-id}/song/{song-id}
Then PUT establishes a liking, and DELETE removes it. GET of course finds out if someone likes a particular song. And you could define GET /like/user/{user-id} to see a list of the songs a particular user likes, and GET /like/song/{song-id} to see a list of the users who like a particular song.
If you assume the user name is established by the existing session, as #joelittlejohn points out, and is not part of the like resource name, then you're violating REST's statelessness constraint and you lose some very important advantages. For instance, a user can only get their own likes, not their friends' likes. Also, it breaks HTTP caching, because one user's likes are indistinguishable from another's.