2017-11-29 10 views
0
class User 
    has_many :addresses 

    def csv_header 
    self.addresses.attribute_names 
    end 

    def csv_values 
    self.addresses.all do |addr| 
     addr.attributes.values 
    end 
    end 
end 

class Address 
    belongs_to :user 
end 

に関連した子モデルから属性名を引っ張るが、この方法では、誰もが*親モデル

+0

[テーブルの列名で配列を取得する方法](https://stackoverflow.com/questions/3479551/how-to-get-an-array-with-column-names-of- A-table) – jvillian

答えて

1

ない助けることができるように機能していませんここに必要なものは - mapaddressesにはcsv_valuesが必要です。

class User 
    has_many :addresses 

    def csv_header 
    addresses.attribute_names 
    end 

    def csv_values 
    addresses.map do |addr| 
     addr.attributes.values 
    end 
    end 
end 

class Address 
    belongs_to :user 
end 

これで解決しますか?

私はコードでわかりやすくするために少しの周りのものをシフトし、delegateを利用するように誘惑されるだろう:

class user 
    ... 
    delegate :attribute_names, to: :addresses, prefix: true, allow_nil: true 
    ... 
end 

class Address 
    ... 
    def self.mapped_values 
    all.map { |addr| addr.attributes.values } 
    end 
    ... 
end 

次に、あなただけのuser.addresses_attribute_namesuser.addresses.mapped_valuesを呼び出すことができます。

ヘッダー配列を得るためには、Address.column_namesを呼び出すこともできます。そうした場合には常に一貫性があります。

希望に役立ちます!


コメントに基づいて更新:どちらか一方

のクラスに(ヘッダを取得するためにUser.column_namesまたはuser.attribute_namesを呼び出す:

ユーザーのために同じことを達成するには、次のように呼び出すことができます前者、後者の例)。

また、ユーザーのマップされた値が必要な場合は、アドレスモデルからself.mapped_valuesメソッドをコピーして使用することができます。これは少し重複していますが、このような一対のメソッドでは、これらを別々のモジュールに分けていくつもりはありません。

最後のヒント - あなたは、ユーザーの集合(すなわち、User.all)からaddressメソッドを呼び出している場合は、非効率的な方法(User.includes(:addresses)...)でデータベースを打つ避けるためにincludeにアドレスを、それを調整することを確認してください。

+0

これは非常に役に立ちます。アドレス属性と組み合わせてユーザーモデルの属性を含めることもできます。 –

+0

朝@MykBKibz - これを含む私の答えを更新しました:) – SRack

関連する問題