質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

データベース設計

データベース設計はデータベースの論理的や物理的な部分を特定する工程です。

Q&A

解決済

2回答

4350閲覧

Ruby on Railsでグループ単位のデータ取扱方法について

seesaajira-

総合スコア107

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

データベース設計

データベース設計はデータベースの論理的や物理的な部分を特定する工程です。

0グッド

0クリップ

投稿2016/05/11 09:23

railsは'4.2.5'を使用しています。
各種テーブルが以下のようなグループ単位になっている場合に、
ログインしたユーザーの所属するグループ情報のみ閲覧編集可能にしたいです。


groupテーブル
・userテーブル(ログインに使用)
・Customerテーブル
・その他各種テーブル


各テーブルにgroup_idを持たせて、ログインしたユーザーのgroup_idで絞り込むしかないのでしょうか?
何か定石のようなものがありましたら教えてもらえないでしょうか?

よろしくお願いします

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

tkow様
丁寧なご回答ありがとうございました。
頂いた回答を参考にサンプルを作成してみました。

他に良い方法があれば教えて下さい。
よろしくお願いします。

<要件>
・サインイン(新規ユーザー作成時)に関連するグループを自動で作成。
・ログインしたユーザーの所属するグループ以外の顧客情報は閲覧編集不可とする。

<モデル>

class Group < ActiveRecord::Base has_many :users has_many :customers end
class Customer < ActiveRecord::Base belongs_to :group end
class User < ActiveRecord::Base # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable and :omniauthable acts_as_voter devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable belongs_to :group attr_accessor :new_group_name # バリデーション前にグループのバリデーションをする before_validation :build_group def build_group @group = Group.new name: new_group_name if @group.valid? # グループのバリデーションエラーが発生しなかった場合、 # 値を設定しておく。Userを保存するときにグループも一緒に作成される self.group = @group else # グループのバリデーションエラーが発生した場合、 # グループのバリデーションエラーのメッセージをUserモデルに設定 @group.errors.each do |_, message| errors.add :new_group_name, message end end end end

<コントローラー>

class CustomersController < ApplicationController before_action :find_customer, only: [:show,:edit,:update,:destroy] def index #ログインしたユーザーグループ情報のみ抽出 @customers = Customer.where(group_id: User.find(current_user).group_id) end def new @group = User.find(current_user).group_id @customer = Customer.new end def create @customer = Customer.new(customer_params) if @customer.save redirect_to @customer else render 'new' end end def update if @customer.update(customer_params) redirect_to @customer else render 'new' end end def edit end def destroy @customer.destroy respond_to do |format| format.html { redirect_to customers_url, notice: 'Group was successfully destroyed.' } format.json { head :no_content } end end def show end private def find_customer #URLに直にidを入力された場合の対処 if Customer.exists?(group_id: User.find(current_user).group_id, id: params[:id]) then @customer = Customer.find(params[:id]) else respond_to do |format| format.html { redirect_to customers_url, notice: 'レコードが存在しません' } format.json { head :no_content } end end end def customer_params params.require(:customer).permit(:name,:zip_code,:address,:tel,:fax,:remarks,:group_id) end end

<View>

= simple_form_for @customer do |f| =f.input :name =f.input :zip_code =f.input :address =f.input :tel =f.input :fax =f.input :remarks =f.input :group_id, :as => :hidden, :input_html => { :value => @group} =f.button :submit

投稿2016/05/13 06:37

seesaajira-

総合スコア107

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

アソシエーション参照が重複し過ぎたりしないように多数の参照から多数の参照にアクセスする頻度を出来るだけ避けるために適切に中間テーブルを入れたり,正規化したり,インデックスを張るなど,基本的な知識を除けば定石というほど定石というものはありません。その辺りの知識が不足されていると思われるようでしたらここで答えられるものを待つよりも書籍やネット等から知識を得たほうが効率がいいでしょう。
本当に基礎ですが知らない話題があれば技術評論社の記事が参考になると思います。

優れているデザインパターンというものは有りますが大体はユーザーの使い方に合わせたアドホックな設計になることの方が多くデータ構造の問題よりも効率の悪いクエリを書いていたり,インデックスを張ってなかったり等の凡ミスが多いと思います。ただ確かに設計を間違えると後で修正しにくいので,大失敗をしない程度に基礎を押さえて,そこから先のチューニングは基本的にはデータをどのように管理したいかで,設計者がその都度スキーマを考えなければいけません。

今回の例ですが,まずはデータが正規化されていなければ正規化すると良いでしょう。これによってgroupテーブルでgroup_idを利用して参照すべきリレーションが絞られるはずです。逆に言うならば第三正規形まで変形させた時データ構造の重複がほとんど排除された状態になるはずなのでこの場合はどんなに量が多くてもすべてのテーブルにカラムを追加するべきです。

それらの基本を理解した上でアクセスを高速にしたいのであれば,グループ毎にユーザーのクラスを別々に設計してテーブルをクラス毎に作成するという工夫があったり,データ集計などを気にするのであればポリモーフィズムを許可して同系統のデータを同じデータベースに保存するなども出来ますし,ある程度日常的なアクセスの高速化を図りつつ集計もしたいのであれば別々のグループに個別のデータベースを作成しつつ,グループテーブルには参照先の集計済みデータを保持するカラムを作ると言った工夫が考えられます。

投稿2016/05/11 19:48

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問