কীভাবে has_many রেকর্ড যুক্ত করবেন: রেল সংঘের মাধ্যমে


97
class Agents << ActiveRecord::Base
  belongs_to :customer
  belongs_to :house
end

class Customer << ActiveRecord::Base
  has_many :agents
  has_many :houses, through: :agents
end

class House << ActiveRecord::Base
  has_many :agents
  has_many :customers, through: :agents
end

আমি কীভাবে Agentsমডেলটিতে যুক্ত করব Customer?

এই সেরা উপায়?

Customer.find(1).agents.create(customer_id: 1, house_id: 1)

উপরের কনসোল থেকে সূক্ষ্ম কাজ করে তবে, আসল প্রয়োগে এটি কীভাবে অর্জন করা যায় তা আমি জানি না।

কল্পনা করুন যে কোনও ফর্ম গ্রাহকের জন্য পূর্ণ হয়েছে যা house_idইনপুট হিসাবেও নেয় । তাহলে আমি কি আমার নিয়ামকটিতে নিম্নলিখিতগুলি করব?

def create 
  @customer = Customer.new(params[:customer])
  @customer.agents.create(customer_id: @customer.id, house_id: params[:house_id])
  @customer.save
end

সামগ্রিকভাবে আমি has_many :throughটেবিলের মধ্যে রেকর্ডগুলি কীভাবে যুক্ত করব তা নিয়ে বিভ্রান্ত ?


আপনি কোন কন্ট্রোলারে "ক্রিয়েশন" ফাংশনটি সংরক্ষণ করবেন?
টোবিয়াস কলব

উত্তর:


166

আমি মনে করি আপনি কেবল এটি করতে পারেন:

 @cust = Customer.new(params[:customer])
 @cust.houses << House.find(params[:house_id])

বা কোনও গ্রাহকের জন্য নতুন বাড়ি তৈরি করার সময়:

 @cust = Customer.new(params[:customer])
 @cust.houses.create(params[:house])

আপনি আইডির মাধ্যমেও যুক্ত করতে পারেন:

@cust.house_ids << House.find(params[:house_id])

16
এফওয়াইআই: পিতামাতা ইতিমধ্যে সংরক্ষিত না হলে আপনি সংশ্লিষ্ট বাড়িটি তৈরি করতে পারবেন না।
রিকার্ডো ওটারো

আমি জুড়ে এসেছি এই সমস্যার সর্বাধিক মার্জিত সমাধান হতে হবে। আপনার জন্য +1
ড্যানিয়েল বনেল

@RicardoOtero আমি মনে করি আমরা ব্যবহার করতে পারেন buildএর istead create?
করণ

@ মিশা যদি হাউস.ফাইন্ড (প্যারামস [: হাউস_আইডি] শূন্য হয় তবে আমার কীভাবে ত্রুটিটি পরিচালনা করা উচিত .. যদি প্যারামগুলি [: হাউস_আইডি] শূন্য থাকে তবে আমি টাইপমিসম্যাচ ত্রুটি পেয়েছি .. আমি ইতিমধ্যে উদ্ধার ব্যবহার করছি। তবে কি আরও ভাল_ও আছে .. ??
বিশাল

4
আমি দেখেছি যে <<অপারেটর ব্যবহার করে নির্দিষ্ট ক্ষেত্রে দু'বার সন্নিবেশ করা যায় does সুতরাং createপদ্ধতিটি সর্বোত্তম উপায়।
অদলবদল করুন

79

'সেরা উপায়' আপনার প্রয়োজন এবং কোনটি সবচেয়ে স্বাচ্ছন্দ্য বোধ করে তার উপর নির্ভর করে। গুলিয়ে ফেলা পার্থক্য ActiveRecord এর আচরণ থেকে আসে newএবং createপদ্ধতি ও <<অপারেটর।

newপদ্ধতি

newআপনার জন্য কোনও সমিতি রেকর্ড যুক্ত করবে না। আপনাকে নিজেই তৈরি করতে হবে Houseএবং Agentরেকর্ড করতে হবে:

house = @cust.houses.new(params[:house])
house.save
agent = Agent(customer_id: @cust.id, house_id: house.id)
agent.save

নোট করুন @cust.houses.newএবং House.newকার্যকরভাবে একই কারণ আপনার Agentউভয় ক্ষেত্রেই রেকর্ড তৈরি করতে হবে ।

<<অপারেটর

মিশা যেমন উল্লেখ করেছেন, আপনি <<সংগ্রহটিতে অপারেটরটিও ব্যবহার করতে পারেন । এটি কেবল Agentআপনার জন্য মডেল তৈরি করবে, আপনাকে অবশ্যই Houseমডেলটি তৈরি করতে হবে :

house = House.create(params[:house])
@cust.houses << house
agent = @cust.houses.find(house.id)

createপদ্ধতি

createআপনার জন্য উভয় Houseএবং Agentরেকর্ড তৈরি করবে, তবে আপনি Agentযদি নিজের ভিউ বা এপিআইতে এটি ফিরিয়ে দিতে চান তবে আপনাকে মডেলটি সন্ধান করতে হবে :

house = @cust.houses.create(params[:house])
agent = @cust.agents.where(house: house.id).first

চূড়ান্ত নোট হিসাবে, যদি আপনি houseপরিবর্তে ব্যাং অপারেটরগুলি তৈরি করার সময় ব্যতিক্রমগুলি উত্থাপন করতে চান (যেমন new!এবং create!)।


4
পরিবর্তে লাইন agent = @cust.houses.find(house.id)পড়া উচিত agent = @cust.agents.find(house.id)? agent"নতুন পদ্ধতি" মধ্যে পরিবর্তনশীল ভিন্ন agentআধুনিক উদাহরণ হবে। যোগদানের টেবিলে অতিরিক্ত গুণাবলী নিয়ে কাজ করা লোকদের জন্য কিছু বিভ্রান্তি তৈরি করতে পারে।
ভান 6

N + 1 বাগের উদাহরণ না দিয়ে আপনি যৌথ টেবিল এজেন্টদের থেকে ডেটা পুনরুদ্ধারের বিষয়ে বিস্তারিত বর্ণনা করতে পারেন প্রদত্ত গ্রাহকের জন্য সমস্ত বাড়ি এবং সংশ্লিষ্ট এজেন্টগুলি প্রদর্শন করে
অঙ্কিতা.পি

6

সমিতি যুক্ত করার আরেকটি উপায় হ'ল বিদেশী কী কলামগুলি ব্যবহার করে:

agent = Agent.new(...)
agent.house = House.find(...)
agent.customer = Customer.find(...)
agent.save

অথবা রেকর্ডের পরিবর্তে সম্পর্কিত রেকর্ডের আইডি পাস করে সঠিক কলামের নাম ব্যবহার করুন।

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