অ্যাক্টিভেকর্ডে তৈরির ক্ষেত্রে ওভাররাইডিং আইডি


104

কোনও মডেলের আইডি মান তৈরির ক্ষেত্রে ওভাররাইড করার কোনও উপায় আছে কি? কিছুটা এইরকম:

Post.create(:id => 10, :title => 'Test')

আদর্শ হতে পারে, তবে অবশ্যই কাজ করবে না।


1
এই উত্তরগুলির মধ্যে অনেকগুলি রেল 4 এর সাথে মাঝে মাঝে ব্যর্থ হবে এবং বলবে যে তারা কাজ করছে। একটি ব্যাখ্যা জন্য আমার উত্তর দেখুন ।
রিক স্মিথ

উত্তর:


116

আইডিটি কেবলমাত্র অ্যাট্রি_প্রোটেক্টেড, এজন্য আপনি সেট করতে ভর-অ্যাসাইনমেন্ট ব্যবহার করতে পারবেন না। তবে ম্যানুয়ালি সেট করার সময় এটি কেবল কাজ করে:

o = SomeObject.new
o.id = 8888
o.save!
o.reload.id # => 8888

আমি আসল প্রেরণাটি কী তা নিশ্চিত নই, তবে অ্যাক্টিহ্যাশ মডেলগুলিকে অ্যাক্টিভেকর্ডে রূপান্তর করার সময় আমি এটি করি। অ্যাক্টিভ্যাশ আপনাকে অ্যাক্টিভেকর্ডে একই সম্পর্কিত_সামেন্টিকগুলি ব্যবহার করার অনুমতি দেয় তবে মাইগ্রেশন এবং একটি টেবিল তৈরি করার পরিবর্তে এবং প্রতিটি কলে ডাটাবেসের ওভারহেড ব্যয় করার পরিবর্তে আপনি কেবলমাত্র আপনার ডেটা yML ফাইলগুলিতে সঞ্চয় করেন। ডাটাবেসের বিদেশী কীগুলি yML- এ মেমরি আইডি উল্লেখ করে।

অ্যাক্টিভ্যাশ পিকলিস্ট এবং ছোট টেবিলগুলির জন্য দুর্দান্ত যা অবিচ্ছিন্নভাবে পরিবর্তিত হয় এবং কেবল বিকাশকারীদের দ্বারা পরিবর্তিত হয়। সুতরাং অ্যাক্টিভ্যাশ থেকে অ্যাক্টিভেকর্ডে যাওয়ার সময়, সমস্ত বিদেশী কী উল্লেখগুলি একই রাখাই সহজ।


@jkndrkn - আপনার অর্থ কী তা আমি জানি না। আমি ActiveRecord::VERSION::STRING == "3.2.11"এখানে এসেছি (স্ক্লাইট 3 অ্যাডাপ্টারের সাথে) এবং উপরেরটি আমার জন্য কাজ করে।
ফেলিক্স রাবে

সম্ভবত আমি যা অভিজ্ঞতা পেয়েছি তা কেবল মাইএসকিএল ড্রাইভারের সাথে প্রকাশ করেছে।
jkndrkn

@jkndrkn আমার কাছে রেল ৩.২.১৮ এর জন্য মাইএসকিউএল ড্রাইভার ব্যবহার করে কাজ করে
লুলালালা

আমার জন্য কাজ। আমার জীবন সংরক্ষিত. রেল 4.0.0 / পোস্টগ্রেসে 9.3.5-এ ব্যবহৃত হয়
এলেনওলি

4 রেলগুলিতে কীভাবে এটি করা যায় তার জন্য আমার উত্তর দেখুন
রিক স্মিথ

30

চেষ্টা

a_post = Post.new do |p| 
  p.id = 10
  p.title = 'Test'
  p.save
end

এটি আপনি যা খুঁজছেন তা আপনাকে দেওয়া উচিত।


2
আপনি কেন অবনমিত হচ্ছেন তা নিশ্চিত নন, এটি আমার জন্য দুর্দান্ত কাজ করে
সিমেন্টিগার্ট

এটি অ্যাক্টিভেকর্ড 3.2.11 হিসাবে কাজ করে চলেছে। ২৯ শে অক্টোবর ২০০৯ এ জেফ ডিন পোস্ট করা উত্তরটি আর কাজ করে না।
jkndrkn

কাজ করে না, কেবল কাজ করা বলে মনে হচ্ছে কারণ p.save কল করা যা সম্ভবত মিথ্যা প্রত্যাবর্তন করছে। একটি অ্যাক্টিভেকর্ড পাবেন :: রেকর্ডনটফাউন্ড আপনি যদি p.save চালিয়ে যান!
অ্যালান

29

আপনি এই জাতীয় কিছু ব্যবহার করতে পারেন:

Post.create({:id => 10, :title => 'Test'}, :without_protection => true)

যদিও দস্তাবেজে বর্ণিত হয়েছে, এটি ভর-নিয়োগের সুরক্ষাটিকে বাইপাস করবে।


সুন্দর সন্ধান করুন, @ সামুয়েল হ্যানি, আমি এ্যাক্টিভেরকর্ড ৩.২.১৩ দিয়ে পুরোপুরি কাজ করে যাচাই করতে পারি।
mkralla11

আমার জন্যও কাজ করেছেন; আলাদা ক্ষেত্র অন্তর্ভুক্ত করার প্রয়োজন ছিল না।
শালট

2
হায়রে, এটি আর 4 রেলগুলিতে কাজ করে না, তারা
হ্যাশগুলি

@ জর্জেসাম্পায়ো - 4 রেলগুলিতে আপনার এটির দরকার নেই কারণ স্ট্রংপ্যারামের পক্ষে সুরক্ষিত গুণাবলী সরানো যেতে পারে।
পিনিএম

21

4 রেলের জন্য:

Post.create(:title => 'Test').update_column(:id, 10)

অন্যান্য পাগল 4 উত্তর হয়নি না আমার জন্য কাজ করে। রেলস কনসোলটি ব্যবহার করার সময় তাদের মধ্যে অনেকে পরিবর্তন করার জন্য উপস্থিত হয়েছিল, কিন্তু আমি যখন মাইএসকিউএল ডাটাবেসে মানগুলি পরীক্ষা করেছি তখন সেগুলি অপরিবর্তিত ছিল। অন্যান্য উত্তরগুলি কেবল কখনও কখনও কাজ করে।

অন্তত মাইএসকিউএল-র জন্য, idঅটো বর্ধিত আইডি নম্বরটির নীচে একটি অ্যাসাইন করা আপনার ব্যবহার না করা কার্যকর হয় নাupdate_column । উদাহরণ স্বরূপ,

p = Post.create(:title => 'Test')
p.id
=> 20 # 20 was the id the auto increment gave it

p2 = Post.create(:id => 40, :title => 'Test')
p2.id
=> 40 # 40 > the next auto increment id (21) so allow it

p3 = Post.create(:id => 10, :title => 'Test')
p3.id
=> 10 # Go check your database, it may say 41.
# Assigning an id to a number below the next auto generated id will not update the db

আপনি যদি + createব্যবহার পরিবর্তন করেন তবে আপনার এখনও এই সমস্যাটি থাকবে। ম্যানুয়ালি এর মতো পরিবর্তন করাও এই সমস্যা তৈরি করে।newsaveidp.id = 10

সাধারণভাবে, আমি এটি update_columnপরিবর্তন করতে ব্যবহার করব idযদিও এটির জন্য অতিরিক্ত ডেটাবেস কোয়েরি ব্যয় হয় কারণ এটি সর্বদা কাজ করবে। এটি এমন একটি ত্রুটি যা আপনার বিকাশের পরিবেশে প্রদর্শিত নাও হতে পারে, তবে কাজ করার সময় চুপচাপ আপনার প্রোডাকশন ডেটাবেসকে নষ্ট করে দিতে পারে।


3
এটি কনসোলের 3.2.22 পরিস্থিতিতে রেলপথে কাজ করার একমাত্র উপায় ছিল। 'সংরক্ষণ করুন' এর প্রকরণগুলি ব্যবহার করে উত্তরগুলির কোনও প্রভাব ছিল না।
জোসেফকে

2
4+ রেলের জন্য আমি ব্যবহার করি:Post.new.update(id: 10, title: 'Test')
স্পেনসর

6

আসলে, দেখা যাচ্ছে যে নিম্নলিখিত কাজগুলি করা:

p = Post.new(:id => 10, :title => 'Test')
p.save(false)

এটি কার্যকর হতে পারে, এটি সমস্ত বৈধতাও বন্ধ করে দেয়, যা জিজ্ঞাসা করা উদ্দেশ্যগুলি নাও হতে পারে।
জর্ডান মনচারমন্ট

আইডির বিষয়টি বিবেচনা করে বীজের ডেটার জন্য আমার ঠিক এটির প্রয়োজন ছিল। ধন্যবাদ.
জেডি।

@ জেডি বলেছে যে আমি বীজ ডেটা নিয়ে কাজ করব এই ভেবে আমি মূলত উজ্জীবিত হয়েছিলাম, তবে তারপরে আমি এটিকে অ্যাক্টিভেকর্ড 3.2.13 দিয়ে চেষ্টা করেছি এবং এখনও "সুরক্ষিত বৈশিষ্ট্য বরাদ্দ করতে পারি না" ত্রুটি পেয়েছি। সুতরাং, ডাউনভোটেড :(
mkralla11

1
দুর্ভাগ্যক্রমে, এটি রেল 4 এ কাজ করে না, আপনি NoMethodError: অপরিজ্ঞাত পদ্ধতি `[] 'মিথ্যা জন্য: ফলস ক্লাস
জর্জি

@ জর্জেসম্পায়ো এটি সরলতার validate: falseপরিবর্তে পাস করলে এটি এখনও কাজ করে false। যাইহোক, আপনি এখনও সুরক্ষিত বৈশিষ্ট্য ইস্যুতে চালিত হন - এর উত্তরের একটি আলাদা উপায় আছে যা আমি আমার উত্তরে উল্লেখ করেছি।
পিনিএম

6

জেফ যেমন উল্লেখ করেছেন, আইডিটি এমনভাবে আচরণ করে যেন এটি অ্যাট্রি_প্রোটেক্টেড। এটি রোধ করতে আপনার ডিফল্ট সুরক্ষিত বৈশিষ্ট্যের তালিকাটি ওভাররাইড করতে হবে। বাইরে থেকে যে কোনও অ্যাট্রিবিউট তথ্য আসতে পারে তা এই জায়গায় সাবধানে করুন। আইডি ফিল্ডটি কোনও কারণে ডিফল্ট সুরক্ষিত।

class Post < ActiveRecord::Base

  private

  def attributes_protected_by_default
    []
  end
end

(অ্যাক্টিভেকর্ড 2.3.5 দিয়ে পরীক্ষিত)


6

আমরা অ্যাট্রিবিউট_রক্ষিত_বিধ্বনি_ডিফল্টকে ওভাররাইড করতে পারি

class Example < ActiveRecord::Base
    def self.attributes_protected_by_default
        # default is ["id", "type"]
        ["type"]
    end
end

e = Example.new(:id => 10000)

5
Post.create!(:title => "Test") { |t| t.id = 10 }

এটি সাধারণত আপনি যে কাজটি করতে চান তা হিসাবে আমাকে আঘাত করে না, তবে আইডির একটি নির্দিষ্ট সেট (উদাহরণস্বরূপ যখন একটি রেক টাস্ক ব্যবহার করে ডিফল্ট তৈরি করার সময়) দিয়ে একটি টেবিল তৈরি করা দরকার তবে এটি বেশ ভালভাবে কাজ করে you অটো-ইনক্রিমেন্টিংকে ওভাররাইড করতে চান (যাতে আপনি প্রতিটি সময় টাস্কটি চালাবেন একই আইডিতে টেবিলটি জনপ্রিয় হয়):

post_types.each_with_index do |post_type|
  PostType.create!(:name => post_type) { |t| t.id = i + 1 }
end

2

এই create_with_id ফাংশনটি আপনার বীজ.rb এর শীর্ষে রাখুন এবং তারপরে এটি স্পষ্টত আইডির পছন্দসই যেখানে আপনার অবজেক্ট তৈরি করতে ব্যবহার করুন।

def create_with_id(clazz, params)
obj = clazz.send(:new, params)
obj.id = params[:id]
obj.save!
    obj
end

এবং এটি এটি ব্যবহার করুন

create_with_id( Foo, {id:1,name:"My Foo",prop:"My other property"})

পরিবর্তে ব্যবহার

Foo.create({id:1,name:"My Foo",prop:"My other property"})


2

এই ক্ষেত্রে একটি অনুরূপ ইস্যু যা প্রয়োজন ছিল idএক ধরণের কাস্টম তারিখ দিয়ে ওভাররাইট :

# in app/models/calendar_block_group.rb
class CalendarBlockGroup < ActiveRecord::Base
...
 before_validation :parse_id

 def parse_id
    self.id = self.date.strftime('%d%m%Y')
 end
...
end

এবং তারপর :

CalendarBlockGroup.create!(:date => Date.today)
# => #<CalendarBlockGroup id: 27072014, date: "2014-07-27", created_at: "2014-07-27 20:41:49", updated_at: "2014-07-27 20:41:49">

কলব্যাকস ঠিকঠাক কাজ করে।

শুভকামনা !.


আমার idইউনিক্স টাইম স্ট্যাম্পের উপর ভিত্তি করে তৈরি করা দরকার । আমি এটা ভিতরে করেছি before_create। ঠিকভাবে কাজ করে.
ডাব্লুএম

0

পাগল 3 জন্য, এই কাজ করতে সহজ উপায় ব্যবহার করা newসঙ্গে without_protectionপরিশোধন, এবং তারপর save:

Post.new({:id => 10, :title => 'Test'}, :without_protection => true).save

বীজ ডেটার জন্য, বৈধতা যা আপনি এটি করতে পারেন তা বাইপাস করার অর্থ হতে পারে:

Post.new({:id => 10, :title => 'Test'}, :without_protection => true).save(validate: false)

আমরা আসলে অ্যাক্টিভেকর্ড :: বেসে একটি সহায়ক পদ্ধতি যুক্ত করেছি যা বীজ ফাইলগুলি কার্যকর করার আগে অবিলম্বে ঘোষণা করা হয়:

class ActiveRecord::Base
  def self.seed_create(attributes)
    new(attributes, without_protection: true).save(validate: false)
  end
end

এবং এখন:

Post.seed_create(:id => 10, :title => 'Test')

রেলস 4 এর জন্য, আপনি সুরক্ষিত বৈশিষ্ট্যের পরিবর্তে স্ট্রংপ্যারাম ব্যবহার করা উচিত। যদি এটি হয় তবে আপনি কোনও পতাকা ছাড়াই কেবল নিয়োগ এবং সংরক্ষণ করতে সক্ষম হবেন new:

Post.new(id: 10, title: 'Test').save      # optionally pass `{validate: false}`

{}উপরে শমূয়েলের উত্তর হিসাবে গুণাবলী না রেখে আমার পক্ষে কাজ করে না (রেল 3)।
ক্রিস্টোফার ওয়েজব্যাক

@ পিনিএম আপনার রেলস 4 টি উত্তর আমার পক্ষে কাজ করে না। idএখনও 10
রিক স্মিথ

@ রিকস্মিথ দেওয়া উদাহরণে id10 হিসাবে পাস হয়েছে - সুতরাং ঠিক এটি হওয়া উচিত। আপনি যদি যা আশা করেছিলেন তা যদি না হয় তবে আপনি কি উদাহরণ দিয়ে স্পষ্ট করে বলতে পারেন?
PinnyM

দুঃখিত, আমি বলতে চাইছি এখনও 10 নয় । একটি ব্যাখ্যা জন্য আমার উত্তর দেখুন।
রিক স্মিথ

@ রিকস্মিথ - আকর্ষণীয়, এই সমস্যাটি কি মাইএসকিউএল এর সাথে অনন্য? যে কোনও ক্ষেত্রে, প্রাথমিক কীগুলি সরাসরি বরাদ্দের জন্য সাধারণ ব্যবহার বীজ ডেটার জন্য। যদি তা হয় তবে আপনার স্বতঃআগ্রহ প্রান্তিকের নীচে থাকা মানগুলি প্রবেশের চেষ্টা করা উচিত নয়, বা আপনাকে এই আদেশগুলির জন্য স্ব-স্বীকৃতি বন্ধ করতে হবে।
PinnyM

0

পোস্টগ্রেস্কেল 9.5.3 এর সাথে 4.2.1 রেলগুলিতে, Post.create(:id => 10, :title => 'Test')যতক্ষণ না ইতোমধ্যে id = 10 এর সারি নেই isn't


0

আপনি এসকিউএল দ্বারা আইডি canোকাতে পারেন:

  arr = record_line.strip.split(",")
  sql = "insert into records(id, created_at, updated_at, count, type_id, cycle, date) values(#{arr[0]},#{arr[1]},#{arr[2]},#{arr[3]},#{arr[4]},#{arr[5]},#{arr[6]})"
  ActiveRecord::Base.connection.execute sql
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.