রেলস হ্যাশ আপত্তি


147

আমার তৈরি করা হয়েছে নিম্নলিখিত বিষয়বস্তু আছে

@post = Post.create(:name => 'test', :post_number => 20, :active => true)

এটি সংরক্ষণ করা হয়ে গেলে আমি বস্তুটিকে একটি হ্যাশে ফিরে পেতে সক্ষম হতে চাই, যেমন কিছু করার মাধ্যমে:

@object.to_hash

রেলের মধ্যে থেকে কীভাবে এটি সম্ভব?

উত্তর:


295

আপনি যদি কেবলমাত্র গুণাবলীর সন্ধান করে থাকেন তবে আপনি সেগুলি পেতে পারেন:

@post.attributes

30
লুপিংয়ের সময়, ব্যয়বহুল পদ্ধতিটি ব্যবহার করবেন না । আস_জসনের সাথে যান
অঙ্কিতজি

5
.to_jsonমডেলটি সম্পূর্ণ না হলে
ডিবিকে

1
joinsএবং এর সাথে কাজ করে select, Person.joins(:address).select("addresses.street, persons.name").find_by_id(id).attributesফিরে আসবে { street: "", name: "" }
2-29

3
@ অঙ্কিতজি আমি বিশ্বাস করি না যে_জসন যে কোনও কম ব্যয়বহুল। যদি আপনি এর উত্স কোডটি লক্ষ্য করেন তবে as_jsonএটি কল করবে serializable_hashযা ঘুরে ফিরে কল করবে attributes! সুতরাং আপনার পরামর্শ আসলে জটিলতার দুটি স্তর যুক্ত করছে attributes, এটি আরও ব্যয়বহুল করে তুলেছে ।
Sandre89

2
.as_jsonবিষয়টি রুবি
হ্যাশকে

45

রেলের সবচেয়ে সাম্প্রতিক সংস্করণে (কোনটি ঠিক তা বলতে পারে না), আপনি এই as_jsonপদ্ধতিটি ব্যবহার করতে পারেন :

@post = Post.first
hash = @post.as_json
puts hash.pretty_inspect

আউটপুট দেবে:

{ 
  :name => "test",
  :post_number => 20,
  :active => true
}

আরও কিছুটা যেতে গেলে, আপনার বৈশিষ্ট্যগুলির উপস্থিতিটি কাস্টমাইজ করার জন্য আপনি এই পদ্ধতিটিকে ওভাররাইড করতে পারেন, এই জাতীয় কিছু করে:

class Post < ActiveRecord::Base
  def as_json(*args)
    {
      :name => "My name is '#{self.name}'",
      :post_number => "Post ##{self.post_number}",
    }
  end
end

তারপরে, উপরের মতো একই উদাহরণ সহ আউটপুট আসবে:

{ 
  :name => "My name is 'test'",
  :post_number => "Post #20"
}

অবশ্যই এটির অর্থ হল আপনাকে কোন স্পেসিফিকালটি উপস্থিত থাকতে হবে তা স্পষ্ট করে নির্দিষ্ট করে দিতে হবে।

আশাকরি এটা সাহায্য করবে.

সম্পাদনা:

এছাড়াও আপনি হাশিফিয়েবল মণিটি পরীক্ষা করতে পারেন ।


ওপি জেএসএনের জন্য জিজ্ঞাসা করেনি, তবে একটি হ্যাশ চেয়েছিল।
ডেভিড হেম্পি

5
@ ডেভিডহেম্পি দয়া করে ডাউনটাটিংয়ের আগে আমার উত্তরটি পুরোপুরি পড়ুন। আমার উদাহরণগুলিতে যেমন দেখানো হয়েছে, এটি হ'ল # এস_জেসন যা করে এবং এর জন্য লক্ষ্যযুক্ত : api.rubyonrails.org/classes/AtivetiveModel/Serializers/… । আমি সেই পদ্ধতির নামটি বেছে নিই নি।
রাফ

25
@object.as_json

মডেল সম্পর্ক অনুসারে জটিল অবজেক্টটি কনফিগার করতে আস_জসনের খুব নমনীয় উপায় রয়েছে

EXAMPLE টি

মডেল প্রচারণা জন্যে দোকান এবং এক হয়েছে তালিকা

মডেল তালিকা অনেক হয়েছে list_tasks এবং প্রতিটি list_tasks অনেক হয়েছে মন্তব্য

আমরা একটি জসন পেতে পারি যা সহজেই এই সমস্ত ডেটা একত্রিত করে।

@campaign.as_json(
    {
        except: [:created_at, :updated_at],
        include: {
            shop: {
                except: [:created_at, :updated_at, :customer_id],
                include: {customer: {except: [:created_at, :updated_at]}}},
            list: {
                except: [:created_at, :updated_at, :observation_id],
                include: {
                    list_tasks: {
                        except: [:created_at, :updated_at],
                        include: {comments: {except: [:created_at, :updated_at]}}
                    }
                }
            },
        },
        methods: :tags
    })

বিজ্ঞপ্তি পদ্ধতি:: ট্যাগগুলি আপনাকে এমন কোনও অতিরিক্ত অবজেক্ট সংযুক্ত করতে সহায়তা করতে পারে যা অন্যের সাথে সম্পর্ক রাখে না। আপনাকে কেবল মডেল প্রচারে নাম ট্যাগ সহ একটি পদ্ধতি নির্ধারণ করতে হবে । এই পদ্ধতিতে আপনার যা প্রয়োজন তা ফিরিয়ে দেওয়া উচিত (উদাহরণস্বরূপ ট্যাগস। সমস্ত)

As_json এর জন্য অফিসিয়াল ডকুমেন্টেশন


এটি সন্ধানের ঠিক আগে একটি কাস্টম ফাংশন তৈরি করেছিল। ক্লাসের জন্য কোনও ক্রিয়া সংজ্ঞায়নের পরিবর্তে একক-ব্যবহারের পদ্ধতিটি চেয়েছিল। কোনও কারণে XML সিরিয়ালাইজেশন পদ্ধতিতে কাজ করার পরেও এটি মিস হয়েছে। to_বৈকল্পিক প্রায় হুবহু একই কাজ মনে হয় as_, বৈকল্পিক উদ্ধৃত আউটপুট ছাড়া। আমি কেবল পছন্দ করি না তা আমার ফিল্টার মানদণ্ডের ক্রম সংরক্ষণ করা ছিল না। এটি বর্ণমালা অনুসারে বাছাই করা হয়েছে বলে মনে হচ্ছে। আমি ভেবেছিলাম যে এটি আমার পরিবেশে থাকা ভয়ঙ্কর_প্রিন্ট রত্নের সাথে সম্পর্কিত, তবে আমি মনে করি না যে এটি ঘটেছে।
পাইসিস

8

আপনি কোনও মডেল অবজেক্টের বৈশিষ্ট্যগুলি হ্যাশ হিসাবে প্রত্যাবর্তন করে ফিরে পেতে পারেন

@post.attributes

অথবা

@post.as_json

as_jsonআপনাকে সমিতি এবং তাদের বৈশিষ্ট্যগুলি অন্তর্ভুক্ত করার পাশাপাশি কোন বৈশিষ্ট্যগুলিকে অন্তর্ভুক্ত / বাদ দিতে হবে ( ডকুমেন্টেশন দেখুন ) নির্দিষ্ট করতে দেয় । যাইহোক, আপনার যদি কেবল বেস অবজেক্টের বৈশিষ্ট্যগুলির প্রয়োজন হয় তবে রুবি ২.২.৩ এবং রেল ৪.২.২ সহ আমার অ্যাপ্লিকেশনটিতে বেঞ্চমার্কিং দেখায় যেটির attributesজন্য অর্ধেকেরও কম সময় প্রয়োজন as_json

>> p = Problem.last
 Problem Load (0.5ms)  SELECT  "problems".* FROM "problems"  ORDER BY "problems"."id" DESC LIMIT 1
=> #<Problem id: 137, enabled: true, created_at: "2016-02-19 11:20:28", updated_at: "2016-02-26 07:47:34"> 
>>
>> p.attributes
=> {"id"=>137, "enabled"=>true, "created_at"=>Fri, 19 Feb 2016 11:20:28 UTC +00:00, "updated_at"=>Fri, 26 Feb 2016 07:47:34 UTC +00:00}
>>
>> p.as_json
=> {"id"=>137, "enabled"=>true, "created_at"=>Fri, 19 Feb 2016 11:20:28 UTC +00:00, "updated_at"=>Fri, 26 Feb 2016 07:47:34 UTC +00:00}
>>
>> n = 1000000
>> Benchmark.bmbm do |x|
?>   x.report("attributes") { n.times { p.attributes } }
?>   x.report("as_json")    { n.times { p.as_json } }
>> end
Rehearsal ----------------------------------------------
attributes   6.910000   0.020000   6.930000 (  7.078699)
as_json     14.810000   0.160000  14.970000 ( 15.253316)
------------------------------------ total: 21.900000sec

             user     system      total        real
attributes   6.820000   0.010000   6.830000 (  7.004783)
as_json     14.990000   0.050000  15.040000 ( 15.352894)

as_json আবার ডেটাবেস ক্যোয়ারী কল করবে, যদি আপনি যোগ মেথো নিয়ে নেস্টেড রিসোস চালাচ্ছেন
টনি হিসিহ

6

এখানে কিছু দুর্দান্ত পরামর্শ দেওয়া হয়েছে।

আমি মনে করি এটি লক্ষ্য করার মতো যে আপনি একটি অ্যাক্টিভেকর্ড মডেলটিকে হ্যাশের মতো আচরণ করতে পারেন:

@customer = Customer.new( name: "John Jacob" )
@customer.name    # => "John Jacob"
@customer[:name]  # => "John Jacob"
@customer['name'] # => "John Jacob"

অতএব, গুণাবলীর একটি হ্যাশ তৈরির পরিবর্তে আপনি বস্তুটি হ্যাশ হিসাবে নিজেই ব্যবহার করতে পারেন।


6

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

def to_hash
 { name: self.name, active: true }
end

2

আপনার যা প্রয়োজন তা নিশ্চিত নন তবে রুবি কনসোলে এটি চেষ্টা করুন:

h = Hash.new
h["name"] = "test"
h["post_number"] = 20
h["active"] = true
h

স্পষ্টতই এটি আপনাকে কনসোলে একটি হ্যাশ ফিরিয়ে দেবে। যদি আপনি কোনও পদ্ধতির মধ্যে থেকে একটি হ্যাশ ফিরে আসতে চান - কেবল "এইচ" এর পরিবর্তে "রিটার্ন এইচ.আইনস্পেক্ট" ব্যবহার করার চেষ্টা করুন, এর অনুরূপ কিছু:

def wordcount(str)
  h = Hash.new()
  str.split.each do |key|
    if h[key] == nil
      h[key] = 1
    else
      h[key] = h[key] + 1
    end
  end
  return h.inspect
end

পোস্টারগুলি রেলগুলিতে অ্যাক্টিভেকর্ড মডেল সম্পর্কে জিজ্ঞাসা করছে।
জেফ্রি হ্যারিংটন


0

স্বানন্দের উত্তর দুর্দান্ত great

আপনি যদি ফ্যাক্টরিগার্ল ব্যবহার করছেন তবে আপনি buildকীটি ছাড়াই বৈশিষ্ট্য হ্যাশ উত্পন্ন করতে এর পদ্ধতিটি ব্যবহার করতে পারেন id। যেমন

build(:post).attributes

0

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

দ্রষ্টব্য: এটি সবার জন্য সুপারিশ করছে না, তবে প্রান্তের মামলাগুলি!


পাগল API ... উপর রুবি থেকে http://api.rubyonrails.org/classes/ActiveRecord/Result.html ...

This class encapsulates a result returned from calling #exec_query on any database connection adapter. For example:

result = ActiveRecord::Base.connection.exec_query('SELECT id, title, body FROM posts')
result # => #<ActiveRecord::Result:0xdeadbeef>

...

# Get an array of hashes representing the result (column => value):
result.to_hash
# => [{"id" => 1, "title" => "title_1", "body" => "body_1"},
      {"id" => 2, "title" => "title_2", "body" => "body_2"},
      ...
     ] ...
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.