Reputation: 42009
I'm wondering if I can get your advice on associations and possibly data-types for a Rails app with a postgres backend I'm starting to build. A user can create an Entry, which has_many :corrections meaning that multiple users can correct the Entry for language mistakes.
The challenging part for me results from the fact that the content for the Entry is broken up into separate strings, each of which will be corrected individually. For example, let's say I create an entry with the title (which is a string) "My Cat" and the content (which is text column) "My cat's name is Felix. He has black hair," then I want to be able to submit a correction for each of those individually. In the new action of my corrections_controller.rb, I did this
def new
@entry = Entry.find(params[:entry_id])
@title = @entry.title
@content = @entry.content.split('.')
@correction = Correction.new
end
So in the views/corrections/new.html.erb, I did this to create a form element for the title and each string in the content of the Entry.rb
<%= @title %>
<%= form_for [@entry, @correction], url: {action: "create"}, html: {class: "nifty_form"} do |f| %>
<%= label_tag(:content, "Content") %>
<%= f.text_area :content, size: "60x12" %>
<%= f.submit "Create" %>
<% end %>
<hr>
<% @content.each do |c| %>
<%= c %>
<%= form_for [@entry, @correction], url: {action: "create"}, html: {class: "nifty_form"} do |f| %>
<%= label_tag(:content, "Content") %>
<%= f.text_area :content, size: "60x12" %>
<%= f.submit "Create" %>
<% end %>
<% end %>
Now, I have a correction form below the Entry.title "My Cat" and for each string of the entry "My cat's name is Felix" and "He has black hair."
This has the following problem (which I think is a problem)
Although I set it up so that an Entry has_many :corrections, that was intended to be that an Entry might be corrected by many different users each of whom will submit one correction. However, the way it's turned out is that if, for example, an entry has ten sentences in the content column, and another user corrects each of the 10 sentences, then that user will have 10 separate corrections.
Is there a recommended way that I can submit, for example, the three corrections for my hypothetical entry ("My Cat", "My Cat's name is Felix", "His Hair is black") into one correction row in the table, keeping each sentence of the Entry linked to the correction by the user, so that when I retrieve my correction from the database I can display the title, its correction, the first sentence with its correction and the second sentence with its correction? I'm thinking hstore might be the way to deal with this but I'm not sure how to go about it.
Based on your answer to question #1, would you split Entry in the corrections_controller.rb into separate instance variables or do something else?
def new
@entry = Entry.find(params[:entry_id])
@title = @entry.title
@content = @entry.content.split('.')
@correction = Correction.new
end
3) If you would use postgres hstore, would you make the sentence to be corrected the key
and the corrected sentence the value
>> Correction.create( :data => { "My Cat's name is Felix" => "My cat's name is Felix", "He has black hair" => "He has black fur"})
Correction.last.data Correction Load (1.0ms) SELECT "corrections".* FROM "corrections" ORDER BY "corrections"."id" DESC LIMIT 1 => {"He has black hair"=>"He has black fur", "My Cat's name is Felix"=>"My cat's name is Felix"}
Based on what I've told you, is there a better way to do this with Rails and postgres?
Note, in the app that I'm using for an inspiration, although there are multiple form fields corresponding to the strings to be corrected, they are all submitted at once once the user clicks 'submit.' This would be what I'm aiming for too.
Models
Entry.rb (has a :title and a :content column)
has_many :corrections
Correction (has one column, :content, as well as :user_id and :entry_id)
belongs_to :entry
Upvotes: 1
Views: 267
Reputation: 9157
It doesn't sound like hstore
would work particularly well here.
Since you're splitting the content into sentences, why not reflect that in the database? Store the content in a sentence
table:
(sentence_id int4, entry_id int4, order int2, content text)
Which also means you don't need special handling for the title, it's just a sentence with order == 0
.
Each correction can then reference a specific sentence, and you are not limited with how many corrections per user you have:
(correction_id int4, sentence_id int4, user_id int4, corrected_content text)
Seems a lot simpler.
Upvotes: 1