রেলস: রেলগুলিতে হ্যাস_ অ্যাসোসিয়েশন সহ বিল্ড ব্যবহার করা


143

এই উদাহরণে, আমি userনা দিয়ে একটি তৈরি করি profile, তারপরে পরে profileসেই ব্যবহারকারীর জন্য একটি তৈরি করব । আমি has_oneঅ্যাসোসিয়েশনের সাথে বিল্ডটি ব্যবহার করার চেষ্টা করেছি তবে তা ফুরিয়েছে। আমি কেবলমাত্র এই কাজটি দেখছি তা ব্যবহার করা has_manyuserশুধুমাত্র সর্বাধিক একটি থাকতে অনুমিত হয় profile

আমি এই চেষ্টা করা হয়েছে। আমার আছে:

class User < ActiveRecord::Base
  has_one :profile
end

class Profile < ActiveRecord::Base
  belongs_to :user
end

কিন্তু যখন আমি করি:

user.build_profile 

আমি ত্রুটি পেয়েছি:

ActiveRecord::StatementInvalid: Mysql::Error: Unknown column 'profiles.user_id' in 'where clause': SELECT * FROM `profiles` WHERE (`profiles`.user_id = 4)  LIMIT 1

রেলপথে 0 বা 1 সমিতি থাকার কোনও উপায় আছে কি?


আপনি ঠিক কি চেষ্টা করেছেন? আপনি দয়া করে কিছু কোড পোস্ট করতে পারেন?
জুল নোগুইরা

উত্তর:


359

buildপদ্ধতি স্বাক্ষরের জন্য আলাদা has_oneএবং has_manyসমিতির।

class User < ActiveRecord::Base
  has_one :profile
  has_many :messages
end

has_manyসংস্থার জন্য বিল্ড সিনট্যাক্স :

user.messages.build

has_oneসংস্থার জন্য বিল্ড সিনট্যাক্স :

user.build_profile  # this will work

user.profile.build  # this will throw error

আরও তথ্যের জন্য has_oneসমিতির ডকুমেন্টেশন পড়ুন ।


28
Has_one এর জন্য আলাদা সিনট্যাক্স আমাকে সর্বদা ধরা দেয় ... বাঁশ!
গ্যালাক্সি

11
এটি মজার বিষয় যে এখানে শীর্ষ রেট দেওয়া এবং স্বীকৃত উত্তর কীভাবে ওপি জিজ্ঞাসা করেছে তার থেকে আলাদা প্রশ্নের উত্তর দিচ্ছে।
আজেদী 32

যদিও যদি ব্যবহারকারী প্রোফাইল থেকে belonged (অর্থাত ব্যবহারকারী টেবিল তার টেবিলে foreign_key profile_id আছে) তারপর এছাড়াও বিল্ডিং হিসাবে অর্থাত উপরে কিন্তু শুধুমাত্র নতুন কর্মের জন্য উল্লিখিত ব্যবহারকারীর জন্য প্রফাইলটি কাজ করবে user.build_profile সম্পাদনার জন্য user.build_profile if user.profile.nil? এবং যদি ব্যবহারকারী তৈরি করার সময় তারপর লিখতে আপনি বিল্ড প্রোফাইল চান accepts_nested_attributes_for :profileএই ব্যবহারকারী মডেল। এবং কোন ফর্মটিতে কোন ব্যবহারকারী তৈরি হচ্ছে তা লিখুন <%= f.simple_fields_for :profile do |p| %>এবং এগিয়ে যান।
উদ্যোগ

তবে কেন এই আলাদা আচরণটি has_one বা has_many এর জন্য রাখা হয়েছিল? ডিজাইনের সময় কিছু কারণ থাকবে, আমি ভাবি এবং আশা করি।
জিজ্ঞাসুবাদ

@ আজেদী 32 উত্তরটি প্রশ্নের শিরোনামের সাথে মেলে তবে শরীরের সাথে নয়। রেলগুলিতে এটি ( build_<association>) বেশ অদ্ভুত এবং অপ্রত্যাশিত আচরণ হিসাবে দেওয়া হয়েছে, প্রকৃত প্রশ্নের উত্তরগুলির চেয়ে আরও অনেক লোক এই উত্তরটির সন্ধান করছেন, যদি আপনি জানেন তবে আমার অর্থ কি।
ম্যাক্স উইলিয়ামস

19

ত্রুটির বার্তাটি ভালভাবে দেখুন। এটা আপনাকে বলছে যে আপনার কলাম প্রয়োজনীয় না user_idমধ্যে প্রফাইল টেবিল । মডেলটিতে সম্পর্ক স্থাপন করা উত্তরের একটি অংশ মাত্র।

আপনাকে একটি মাইগ্রেশন তৈরি user_idকরতে হবে যা প্রোফাইল সারণীতে কলামটি যুক্ত করে । রেলগুলি এটির উপস্থিতি প্রত্যাশা করে এবং এটি না হলে আপনি প্রোফাইলটি অ্যাক্সেস করতে পারবেন না।

আরও তথ্যের জন্য দয়া করে এই লিঙ্কটি একবার দেখুন:

সমিতি বেসিক


1
আমি কেবল আমার সমস্যাটি বের করেছিলাম। আমি যে বইটি শিখছি সেটিতে বিদেশী কী তৈরির বিষয়টি খুব ভালভাবে ব্যাখ্যা করা হয়নি। আমি একটি নতুন স্থানান্তর তৈরি করেছি যা আমার মডেলটিতে একটি বিদেশী কী যুক্ত করে। ধন্যবাদ।
এসপিনেট

আপনার কি প্রতি বার কলাম তৈরি করার দরকার আছে? আমার ধারণা ছিল যে এটি স্বয়ংক্রিয়ভাবে ঘটেছিল। আমি জানি না কোথায় আমি এই ধারণা পেয়েছিলাম।
রিমিয়ান

কমান্ড-লাইনের সাহায্যে ব্যবহার করে, ভালো কিছু একটি মডেল উৎপন্ন আপনি কলাম যোগ করতে পারেন rails g model profile user:references:index address:string bio:text
দুয়খোয়া

1

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

old_profile = instance_method(:profile)
define_method(:profile) do
  old_profile.bind(self).call || build_profile
end

এখন #profileপদ্ধতিটি কল করা হয় সম্পর্কিত প্রোফাইলটি ফেরত দেবে বা একটি নতুন উদাহরণ তৈরি করবে।

উত্স: বানর যখন কোনও পদ্ধতিতে প্যাচিং করে, আপনি কি নতুন বাস্তবায়ন থেকে ওভাররাইড পদ্ধতিতে কল করতে পারেন?


1
বর্তমান পাগল মধ্যে (6.0.2.2 উপর পরীক্ষা) আপনি এই প্রক্রিয়া সহজ করতে পারেন: def profile; super || build_profile; end
গ্লাজজ

-14

এটি হওয়া উচিত একটি has_one। যদি buildকাজ না করে থাকে তবে আপনি কেবল ব্যবহার করতে পারেন new:

ModelName.new( :owner => @owner )

হিসাবে একই

@owner.model_names.build

11
এটি একই নয়: আপনি যদি বিল্ড সহ একটি নতুন মডেল_নাম তৈরি করেন, @ মালিক যখন সংরক্ষণ করা হয় তবে নতুন মডেল_নামটিও সংরক্ষণ করা হবে। সুতরাং, আপনি পিতামাতা এবং বাচ্চাদের তৈরি করতে বিল্ডটি ব্যবহার করতে পারেন যা একসাথে সংরক্ষণ হবে। আপনি নতুন। দিয়ে একটি মডেল_নাম তৈরি করেন তবে কেস নয়
ম্যাক্স উইলিয়ামস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.