রেলস অ্যাক্টিভেকর্ড মাইগ্রেশনে রুবিতে আমি কীভাবে দীর্ঘ সূচীর নামগুলি পরিচালনা করব?


391

আমি একটি অনন্য সূচক যুক্ত করার চেষ্টা করছি যা চারটি সম্পর্কিত টেবিলের বিদেশী কী থেকে তৈরি হয়:

add_index :studies,
  ["user_id", "university_id", "subject_name_id", "subject_type_id"],
  :unique => true

সূচকের নামের জন্য ডাটাবেসের সীমাবদ্ধতার ফলে স্থানান্তর ব্যর্থ হয় causes ত্রুটি বার্তাটি এখানে:

সূচকের নাম 'সূচক_স্তাদী_অন_ ব্যবহারকারীর_আইডি_ এবং_বৈচিত্র্য_আইডি_ এবং_সুবজেক্ট_নাম_আইডি_আর_সুবজেক্ট_ টাইপ_আইডি' টেবিলে 'অধ্যয়ন' খুব দীর্ঘ; সীমা 64 অক্ষর

আমি কীভাবে এটি পরিচালনা করতে পারি? আমি কি আলাদা সূচকের নাম উল্লেখ করতে পারি?

উত্তর:


589

:nameবিকল্পগুলি প্রদান করুন add_index, যেমন:

add_index :studies,
  ["user_id", "university_id", "subject_name_id", "subject_type_id"], 
  :unique => true,
  :name => 'my_index'

যদি কোনও ব্লকের :indexবিকল্পটি ব্যবহার করে , এটির মান হিসাবে একই বিকল্পগুলি হ্যাশ নেয় :referencescreate_tableadd_index

t.references :long_name, index: { name: :my_index }

2
এপিআইডক অনুসারে নামটি স্ট্রিং হতে হবে, প্রতীক নয়
জ্যাকো প্রিটোরিয়াস

7
remove_index :studies, :name => 'my_index'এটির জন্য ডাউন সিনট্যাক্সটি যার যার প্রয়োজন এটি
কার্ক

অন ​​রেলগুলির সাথে 4.2.6কাজ করে index: { name: :my_index }। শুধু nameকাজ হয়নি।
Monteirobrena

174

আপনি কোনও create_tableব্লকের মধ্যে কলাম সংজ্ঞাতে সূচকের নামও পরিবর্তন করতে পারেন (যেমন আপনি মাইগ্রেশন জেনারেটর থেকে পান)।

create_table :studies do |t|
  t.references :user, index: {:name => "index_my_shorter_name"}
end

5
নোট করুন যে এটি মূল প্রশ্ন থেকে বহু-কলাম সূচক তৈরি করে না; এটি কেবল প্রদর্শন করছে যে কীভাবে একটি দীর্ঘ সূচকের নামটি ছোট করা যায়create_table
ক্রেগ ওয়াকার

6
এটি আমাকে সাহায্য করেছিল যখন আমি কোনও সূচক সহ একটি নামের ফাঁকে থাকা টেবিলে বহুবৈচিত্র্যমূলক রেফারেন্স তৈরি করার চেষ্টা করছিলাম যখন t.references :searchable, polymorphic:true, index: {:name => "index_searches_on_searchable"}এই ক্ষেত্রে সূচকটি আসলে একটি বহু-কলাম (সন্ধানযোগ্য_আইডি এবং সন্ধানযোগ্য_প্রকার) ছিল এবং উত্পাদিত নামটিতে নামের স্থানটি খুব দীর্ঘ হয়ে যায় ।
mkrinblk

আমার জন্য কমপ্যাক্ট সমাধান। ধন্যবাদ!
সার্জিও বেলভস্কিচ

3
এছাড়াও থাকতে হবে foreign_key: trueএবং যাইহোক, এটি একটি দুর্দান্ত সমাধান যেহেতু আপনি যখন রেল জেনারেটর model:referencesফর্ম্যাট দিয়ে কোনও মাইগ্রেশন ফাইল তৈরি করেন তখন এটি ব্যবহার করা সবচেয়ে সহজ
আব্রাম

39

পোস্টগ্রি সালে ডিফল্ট সীমা 63 অক্ষর । সূচকের নামগুলি অবশ্যই অনন্য হতে হবে কারণ এটি একটি সামান্য সম্মেলন করা ভাল to আমি ব্যবহার করি (আরও জটিল নির্মাণের ব্যাখ্যা দেওয়ার জন্য আমি উদাহরণটি টুইট করেছি):

def change
  add_index :studies, [:professor_id, :user_id], name: :idx_study_professor_user
end

সাধারণ সূচকটি হ'ল:

:index_studies_on_professor_id_and_user_id

যুক্তিটি হ'ল:

  • index হয়ে idx
  • একক টেবিলের নাম
  • যোগদানের শব্দ নেই
  • না _id
  • বর্ণা ক্রমানুসারে

যা সাধারণত কাজ করে।


1
ভাগ করে নেওয়ার জন্য ধন্যবাদ. সীমাবদ্ধতার সত্যতার জন্য পোস্টগ্র্রেস ডকুমেন্টেশনগুলিতে লিঙ্ক করতে পারলে ভাল হবে।
জেজেডি 26'15

সূচি যেভাবেই সেই টেবিলের অন্তর্ভুক্ত তাই আমাদের কি সূচির নামটিতে টেবিলের নাম দরকার? এটি কৌতূহলজনক যদি এটি কোথাও উপকারী হয় তবে আমি দেখিনি।
জোশুয়া পিন্টার 4

আপনি যা চান তা সূচকটির নাম রাখতে পারেন তবে আমার মনে হয় সূচকের নামের টেবিলের নাম সূচকের নামটি অনন্য রাখতে সহায়তা করে (যা বাধ্যতামূলক), ভালভাবে স্কুপ করে কিছু ত্রুটি বার্তার পাঠযোগ্যতার উন্নতি করে।
পরিবেশগত


6

পূর্ববর্তী উত্তরের মতো: আপনার নিয়মিত অ্যাড_ইন্ডেক্স লাইনের সাথে 'নাম' কীটি ব্যবহার করুন:

def change
  add_index :studies, :user_id, name: 'my_index'
end

2

আমি ভয় করি যে এই সমাধানগুলির কোনওোটাই আমার পক্ষে কাজ করে নি। সম্ভবত যেহেতু আমি belongs_toএকটি পলিমারফিক অ্যাসোসিয়েশনের জন্য আমার ক্রিয়েটিটেবল মাইগ্রেশনটি ব্যবহার করছিলাম।

আমি নীচে আমার কোড এবং সমাধানের একটি লিঙ্ক যুক্ত করব যা পলিমারফিক সংঘের সাথে সম্পর্কিত হয়ে 'সূচকের নামটি দীর্ঘ' সন্ধানের সময় অন্য কেউ যদি হোঁচট খায় তবে আমাকে সহায়তা করেছিল।

নিম্নলিখিত কোডটি আমার পক্ষে কার্যকর হয়নি:

def change
  create_table :item_references do |t|
    t.text :item_unique_id
    t.belongs_to :referenceable, polymorphic: true
    t.timestamps
  end
  add_index :item_references, [:referenceable_id, :referenceable_type], name: 'idx_item_refs'
end

এই কোডটি আমার জন্য কাজ করে:

def change
  create_table :item_references do |t|
    t.text :item_unique_id
    t.belongs_to :referenceable, polymorphic: true, index: { name: 'idx_item_refs' }

    t.timestamps
  end
end

এটিই এসও প্রশ্নোত্তর যা আমাকে সাহায্য করেছে: https://stackoverflow.com/a/30366460/3258059


1

আমি এই সমস্যা ছিল, কিন্তু timestampsফাংশন দিয়ে। এটি আপডেটড্যাট-এ একটি সূচককে স্বয়ংক্রিয়ভাবে তৈরি করেছিল যা the৩ টি অক্ষরের সীমা ছাড়িয়ে গেছে:

def change
  create_table :toooooooooo_loooooooooooooooooooooooooooooong do |t|
    t.timestamps
  end
end

সূচকের নাম 'সূচী_টুওoooooo_ লুওooooooooooooooooooooooooooong_on_updated_at' টেবিলের 'টুওoooooo_loooooooooooooooooooooooooooooooong' অনেক দীর্ঘ; সীমা 63 অক্ষর

আমি timestampsসূচকের নামটি নির্দিষ্ট করতে ব্যবহার করার চেষ্টা করেছি :

def change
  create_table :toooooooooo_loooooooooooooooooooooooooooooong do |t|
    t.timestamps index: { name: 'too_loooooooooooooooooooooooooooooong_updated_at' }
  end
end

তবে এটি সূচকের নামটি ক্ষেত্র updated_atএবং created_atক্ষেত্র উভয় ক্ষেত্রেই প্রয়োগ করার চেষ্টা করে :

সূচকের নাম 'too_long_updated_at' টেবিলটিতে 'tooooooooooo_loooooooooooooooooooooooooooooooong' ইতিমধ্যে বিদ্যমান

অবশেষে আমি ছেড়ে দিয়েছি timestampsএবং সবেমাত্র দীর্ঘ পথের টাইমস্ট্যাম্পগুলি তৈরি করেছি:

def change
  create_table :toooooooooo_loooooooooooooooooooooooooooooong do |t|
    t.datetime :updated_at, index: { name: 'too_long_on_updated_at' }
    t.datetime :created_at, index: { name: 'too_long_on_created_at' }
  end
end

এটি কাজ করে তবে আমি timestampsপদ্ধতিটি দিয়ে এটি সম্ভব কিনা তা শুনতে পছন্দ করব !



0

আমার একটি প্রকল্প রয়েছে যা জেনারেটরগুলিকে প্রচুর পরিমাণে ব্যবহার করে এবং এটি স্বয়ংক্রিয় হওয়ার দরকার পড়ে, তাই আমি index_nameএটিকে ওভাররাইড করার জন্য রেলস উত্স থেকে ফাংশনটি অনুলিপি করেছি। আমি এটি এতে যুক্ত করেছি config/initializers/generated_index_name.rb:

# make indexes shorter for postgres
require "active_record/connection_adapters/abstract/schema_statements"
module ActiveRecord
  module ConnectionAdapters # :nodoc:
    module SchemaStatements
      def index_name(table_name, options) #:nodoc:
        if Hash === options
          if options[:column]
            "ix_#{table_name}_on_#{Array(options[:column]) * '__'}".slice(0,63)
          elsif options[:name]
            options[:name]
          else
            raise ArgumentError, "You must specify the index name"
          end
        else
          index_name(table_name, index_name_options(options))
        end
      end
    end
  end
end

এটি সূচকগুলি তৈরি করে ix_assignments_on_case_id__project_id এবং এটি যদি খুব দীর্ঘ হয় তবে এটি 63 টি অক্ষরে ছাঁটাই করে। এটি এখনও অ-অনন্য হতে চলেছে যদি টেবিলের নামটি দীর্ঘ হয় তবে আপনি কলামের নামগুলি থেকে আলাদাভাবে টেবিলের নামটি সংক্ষিপ্ত করা বা স্বতন্ত্রতার জন্য পরীক্ষা করার মতো জটিলতা যুক্ত করতে পারেন।

দ্রষ্টব্য, এটি একটি রেল 5.2 প্রকল্পের; যদি আপনি এটি করার সিদ্ধান্ত নেন তবে আপনার সংস্করণ থেকে উত্সটি অনুলিপি করুন।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.