Le contenu de cet article est actuellement en attente de révision et pourrait changer!
Laissez littéralement hériter une table de la classe parent à la classe enfant!
Dans ce cas, le parent Tweet
→ enfant Mediatweet`` Texttweet
. Classes pour les tweets médiatiques et les tweets texte, respectivement!
Cependant, comme les tables sont les mêmes, toutes les classes, parents et enfants, ont les mêmes colonnes.
Ainsi, Mediatweet
a aussi une colonne content
, et ** Texttweet
a aussi une colonne ʻimg`. ** **
db/schema.rb
create_table "tweets", options: hogehoge
t.text "content"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.string "img"
t.integer "user_id"
t.string "type"
end
Il sera plus facile d'écrire les différences dans le modèle. Par exemple, si vous écrivez une validation sans espaces uniquement dans le texttweet, l'image peut être tweetée sans texte. Cependant, comme le contenu est presque le même, les STI qui peuvent partager la table sont bonnes.
db / schema.rb
, mais laissez la classe parent (table) avoir une colonne type
(type chaîne).rails g model
etc. et créez le modèle enfant etc. directement dans ʻapp / model /`models/tweet.rb
class Tweet < ApplicationRecord
end
models/mediatweet.rb
class Mediatweet < Tweet
end
models/texttweet.rb
class Texttweet < Tweet
end
Pour le moment, c'est la fin de la mise en œuvre des STI. Le reste se fera automatiquement.
Par exemple, si vous enregistrez la base de données avec Mediatweet.create
etc., un enregistrement contenant Mediatweet
et des données sera ajouté à la colonne type
.
Je veux trier les modèles automatiquement en fonction de l'existence ou non de données multimédias, je l'ai donc implémenté comme suit.
index.html.erb
<%= form_with model: @tweet, url: tweets_path do |form| %>
<%= form.text_area :content %><br>
<%= form.label "Télécharger l'image" %><br>
<%= form.file_field :img %>
<%= form.submit 'Publier' %><br>
<% end %>
Cette fois, c'est une page de publication et de liste qui a un formulaire de publication tel qu'il est dans l'index.
Le téléchargeur d'images est implémenté dans carriewave
. Je vais omettre cela.
Les paramètres soumis en soumettant le formulaire ci-dessus sont
{
"authenticity_token"=>"hoge",
"tweet"=>{"content"=>"hoge", "img"=>"hoge"},
"commit"=>"Publier"
}
Vous pouvez obtenir les paramètres d'une structure double comme celle-ci (une structure avec {} à l'intérieur {}).
Et il correspond automatiquement à l'action de création du contrôleur
tweets_controller.rb
def create
@tweet = tweettype_class.new(tweet_params)
if @tweet.save
redirect_to("/tweets")
else
@tweets = Tweet.all.order(created_at: :desc)
render("index")
#Le rendu revient à la page originale de la liste des articles._Si vous ne spécifiez pas l'URL de avec
#form_La racine de with est tirée par le modèle enfant et une erreur se produit (par exemple)Anciennes tétines_chemin Après le rendu → tweets de texte_le chemin n'est pas grand-chose.
end
end
private
def tweet_params
#Seule la partie où la clé est tweet est extraite par require({"content"=>"hoge","img"=>"hoge"})
params.require(:tweet).permit(:content, :img).merge(user_id: @current_user.id)
end
#[:img]Les modèles sont triés selon la présence ou l'absence de données
#Comme il a une structure double, la valeur ne peut pas être obtenue correctement à moins que la clé ne soit également spécifiée deux fois.
def tweettype
case
when params[:tweet][:img].present?
'mediatweet'
when params[:tweet][:img].blank?
'texttweet'
end
end
#Convertit la chaîne de caractères reçue en cas de chameau,De plus, il est converti en un nom constant
#(Exemple) mediatweet.cmelize=>Mediatweet.constantize=>Mediatweet(id: integer, content: text, created_at: datetime, hogehoge.... )
def tweettype_class
tweettype.camelize.constantize
end
Comme ça, j'ai essayé de trier les modèles automatiquement selon que l'image était téléchargée ou non.
Cela a facilité l'écriture de différents rôles pour chaque modèle!