5

私は、CMS のように動作する Rails の Web アプリで作業しています。他の記事 (または他のオブジェクト クラス) へのリンクを含むテキスト属性を持つ記事があります。現在、属性を HTML として保存しています。

これらのリンクを比較的簡単に変更できる方法でモデル化し、絶対 URL の代わりにオブジェクト ID への参照を含める良い方法はありますか?

私が考えていた解決策の 1 つは、次のような特別なマークアップを使用することでした。

[link_to "Text for the link", Article:12]

ここで、12 はリンク先の記事の ID です。このマークアップは、テキストがレンダリングされるときに解析されます。

これの欠点は、データベースにアクセスしてオブジェクトの種類と ID (テキストを編集している人はIDを知りません)。

これに対する簡単な解決策はありますか?

それとも、絶対 URL を使用することに固執する必要がありますか (これは、メンテナンスの問題に加えて、常に本番環境を指し示すため、開発時に煩わしく、私にとって混乱を招きます)?

さらに、他の言語 (php、Wordpress、他の CMS など) でこの問題にうまく取り組んでいる同様の例はありますか? これは CMS では非常に重要であり、優れたシステムがこれらすべてのリンクを処理できれば、工数を大幅に削減できると考えています。

編集:

私が考えている別の可能な解決策は、記事のリンクをコードに直接コピーさせることですが、送信時に正しい関連付け ID を生成し、URL 構造が変更された場合にリンクが常に最新。このアプローチを試したことがあれば、意見や経験をお聞きしたいと思います。

このアプローチの課題は、Rails とのリンクを解析し、それが Article を指していること、およびその記事が id を持っていることを見つけること##です。次に、解析およびレンダリング時に常にその記事への実際のリンクに変換されるショートコードを挿入する必要があります。

これを実現できる方法を見つけました:

Rails.application.routes.recognize_path

しかし、私が今見ていないいくつかの警告があるかもしれません...

編集番号 2

また、コンテンツ エディターとしてCKEditorを選択したことも明記したいと思いますが、より明確な利点があれば他のものも検討します。

4

4 に答える 4

2

記事は多くの related_articles を持つことができ、同時にこの記事は他の多くの記事によって関連付けられる可能性があるため、これを多対多の関係としてモデル化するのが最善です。

Rails でこのタイプの関係を定義する 1 つの方法は、 ですhas_many :through

使用has_many :throughするには、結合モデルを作成する必要があります。おそらくArticleRelationと呼びます。このモデルには、現在の記事を表すarticle_idと、関連記事として参照されている記事を表すrelated_article_idの2 つのフィールドがあります。

class Article < AR::Base
  has_many :article_relations
  has_many :related_articles, :through => :article_relations
end

class ArticleRelation < AR::Base
  belongs_to :article
  belongs_to :article_relation, :class_name => 'Article'
end

自己参照関係を作成するときは、関係の片側だけを作成していることを覚えておくことが重要です。article_1はarticle_2を関連としてリストするかもしれませんが、 article_2がarticle_1を関連としてリストする方法はありません。相互関係を作成するには、 2 つのArticleRelationレコードが必要です。

関係の別の側面を定義する適切な名前を考え出すのは難しいため、両方の前に「逆」という単語を付けて、 inverse_article_relationsinverse_related_articlesを指定できます。また、関係を機能させるには、いくつかの追加オプションを指定する必要があります。inverse_article_relationsの場合、関係名からは推測できないため、他のモデルの名前を指定する必要があります。また、外部キーをrelated_article_idとして定義する必要があります。inverse_related_articles関係の場合は、関係の名前から推測できないため、ソースを article として指定する必要があります

has_many :inverse_article_relations, :class_name => "ArticleRelation", :foreign_key => "related_article_id"
has_many :inverse_related_articles, :through => :inverse_article_relations, :source => :article

テストしてみてください。これは、現在の要件に従って機能するはずです。

于 2013-01-02T19:31:59.270 に答える
2

モデルで特定のメソッドを呼び出し、テキスト内のショートコードを置き換えることができるショートコード システムを使用して、同様のものを構築しました。

ヘルパー

def parse_shortcode(model)
  text = model.text      
  text.gsub(/(\[#!\s?\w+\])/i) do |match|
    result = model.try(match)
    result.nil? '' : link_to(result[:text], result[:url])
  end
end

モデル

def contact_link
  { :text => self.name, :url => self.url }
end

意見

<%= parse_shortcode(@article) %>

私は上記のコードをテストしていません。明らかに少し単純化されていますが、この背後にある私の思考プロセスを説明しています。

編集:上記の例を明確にするために、発明されたショートコード構文を使用しています[#! method]

于 2013-01-08T16:40:44.840 に答える
1

他の多くのCMSで見た解決策は、TinyMCEのカスタムファイルブラウザとページの書き換え(freakyDazの回答と同様)の組み合わせです。

TinyMCEには、カスタムブラウザを実装するためのドキュメントとサンプルコードがあります。もちろん、バックエンド部分を提供する必要があります。

CKEditorには、同様の機能に関するドキュメントもあります。

バックエンドの実装でURLを解析しやすいもの(たとえば、urlfor:Article:12)を返し、レンダリングコードでそれらを実際のURLに置き換えます。

于 2013-01-08T16:54:45.707 に答える
0

ユースケースの別の可能な解決策を考えました:

  1. admin ユーザーは、テキストを編集する前に関係を指定します ( Chosen.jsを使用すると、ユーザーフレンドリーな方法で行うことができます)。
  2. 次に、フォームを送信してモデルを保存するか、非同期で行うことができます。
  3. リレーションシップが保存されると、それぞれのショートコードが生成されて表示されます。そのショートコードはテキストに簡単に貼り付けることができます。
  4. フロントエンドにテキストを表示すると、@freakyDazが提案しているものと同様の方法で、ショートコードのテキストが解析されます。

このように、エディターでカスタム アクションをハッキングしたり作成したりする必要はありません。かなり現実的な方法だと思いますが、皆様のご意見をお聞かせください。もちろん、テキストを作成している管理者は、この順序でプロセスに従うように教育されている必要がありますが、私の場合、管理者になることができる人は非常に少ない (1 人か 2 人) ので、管理しやすいです。

于 2013-01-09T19:29:00.017 に答える