2016-04-08 16 views
1

私は、フォーム(「チェックリスト」という名前)を記入してから、彼がしなければならないタスクのリストをユーザが持つことができるアプリケーションを持っています。タスク(「アドバイス」と呼ばれる)は、ユーザーがフォームに入力した回答に関連しています。 たとえば、質問が「あなたは夕食を作ったのですか?ユーザが「いいえ」と答えた場合、アドバイス「夕食を作る」が表示されます。ユーザー、フォーム、およびタスクの関連付けのレール

アドバイスが完了すると、ユーザーは完了とマークできます。アドバイスはすべてのユーザーで同じです。それらは既にadminによって管理者によって作成されています。

ユーザーにチェックリストがあるので、チェックリストはユーザーに属します。

私が遭遇する問題は、ユーザーが完了としてアドバイスをマークすると、すべてのユーザーに対して完了としてマークされます。そうではありません。

この問題を解決する方法がわかりません。ユーザーがアドバイスを作成しないため、アドバイスとユーザー間の関連性「Has-Many」と「Belongs_to」は機能しませんか?

私はレールが新ですので、誰かが助けてくれたらうれしいです。 私はDeviseを使用してユーザーを管理しています。

スキーマ:

ActiveRecord::Schema.define(version: 20160407143608) do 

    create_table "advices", force: :cascade do |t| 
    t.string "name" 
    t.text  "content" 
    t.datetime "created_at", null: false 
    t.datetime "updated_at", null: false 
    t.integer "category_id" 
    t.boolean "status" 
    t.string "linkname1" 
    t.text  "link1" 
    t.text  "link2" 
    t.string "linkname2" 
    t.text  "link3" 
    t.string "linkname3" 
    t.integer "ref" 
    t.boolean "completed" 
    end 

    create_table "categories", force: :cascade do |t| 
    t.string "name",  null: false 
    t.datetime "created_at", null: false 
    t.datetime "updated_at", null: false 
    end 

    create_table "checklists", force: :cascade do |t| 
    t.boolean "facebook" 
    t.boolean "twitter" 
    t.boolean "linkedin" 
    t.boolean "viadeo" 
    t.boolean "instagram" 
    t.boolean "community" 
    t.boolean "cms" 
    t.boolean "seo" 
    t.boolean "crowdfunding" 
    t.datetime "created_at", null: false 
    t.datetime "updated_at", null: false 
    t.integer "user_id" 
    end 

    add_index "checklists", ["user_id"], name: "index_checklists_on_user_id" 

    create_table "users", force: :cascade do |t| 
    t.string "email",     default: "", null: false 
    t.string "encrypted_password",  default: "", null: false 
    t.string "reset_password_token" 
    t.datetime "reset_password_sent_at" 
    t.datetime "remember_created_at" 
    t.integer "sign_in_count",   default: 0, null: false 
    t.datetime "current_sign_in_at" 
    t.datetime "last_sign_in_at" 
    t.string "current_sign_in_ip" 
    t.string "last_sign_in_ip" 
    t.datetime "created_at",       null: false 
    t.datetime "updated_at",       null: false 
    end 

    add_index "users", ["email"], name: "index_users_on_email", unique: true 
    add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true 

end 

モデル:

class Advice < ActiveRecord::Base 
    belongs_to :category 
end 

class Checklist < ActiveRecord::Base 
    belongs_to :user 
end 

class User < ActiveRecord::Base 
    # Include default devise modules. Others available are: 
    # :confirmable, :lockable, :timeoutable and :omniauthable 
    devise :database_authenticatable, :registerable, 
     :recoverable, :rememberable, :trackable, :validatable 
    has_many :checklists 
end 

ビュー:

<%= advice.name %> | <%= link_to "Completed", complete_advices_path(advice), method: :put %> 

コントローラ:

def complete 
    @advice.completed = true 
    @advice.save 
    redirect_to root_path 
    end 

答えて

1

参加モデルが必要です。 advice.rbで

$ rails g model UserAdvice user:references advice:references

class UserAdvice 
    belongs_to :user 
    belongs_to :advice 
end 
user.rbで

has_many :user_advices 
has_many :advices, through: :user_advices 

has_many :user_advices 
has_many :users, through: :user_advices 

何かがオフに確認しますときに参加モデルでレコードを作成し、そのクエリをタスクが個々のユーザーに対して実行されていることを確認します。

ユーザーがタスクをオフにチェックし、提出し、代わりにcompletedブール値を使用するときに、あなたが実際にadvice_iduser_idを持つレコードを作成したいです。次に、そのアドバイスのレコードが存在する場合は、そのユーザーに対してチェックされている必要があります。それは理にかなっていますか?

あなたがそれらを完了したユーザーからの完了したタスクを隠していた場合、たとえば、あなたはこれが働く、と最初は結構ですが、それをこのようにやっては遅くなる場合があります

<% if UserAdvice.where(user_id: current_user.id, advice_id: advice.id).count > 0 %> 

ような何かを言うことができるが、あなたのアプリをダウン。アドバイスがたくさんある場合は、クエリを一度実行してuser_adviceのレコードをすべて取得し、IDを取得します。次に個々のレコードに対してそのIDの配列をチェックします。次に、あなたのコントローラで

# this will return an array of advice_ids 
@user_advices = UserAdvice.where(user_id: current_user).pluck(:advice_id) 

、あなたはあなたのビューでのアドバイスを反復として:

<% unless @user_advices.include?(advice.id) %> 
    show the advice 
<% end %> 

はEDIT:

その完全なアクション内のレコードを作成するには:

def complete 
    UserAdvice.create(user_id: current_user.id, advice_id: @advice.id) 
    redirect_to root_path 
end 
+0

ありがとうございますあなたの答えのためにdmetheny。うん、私は結合モデルを生成し、user.rbとadvice.rbに新しい関連付けを追加しました。しかし、実際にはどうしたらいいのか分かりません。あなたは模範を持っていますか? – Ryley38

+0

@ Ryley38はいくつかの編集を加えました。私が必要ならさらに説明することができます。 – toddmetheny

+0

私はまたいくつかの編集を追加しました。これらの詳細をありがとうございます。 はい完了したブール値が "false"の場合、アドバイスを表示することを目指しました。 現在、ビュー内のリンクをクリックすると、ユーザーはブール値を変更する「完了」アクションを呼び出します。だから、このアクションは代わりにuser_adviceレコードを作成する必要がありますか? Newbyの質問に申し訳ありませんが、アクションでそれを作成する適切な方法は何ですか? – Ryley38

関連する問題