2017-11-28 4 views
0

bitte einfach auf mir gehen, wie ich nur ein Anfänger bin, breche ich meinen Kopf zu diesem Thema für die jetzt 2 Tage vorbei. Um es zusammenzufassen, habe ich einen Benutzer und productplan, wenn ein Benutzer einen bestimmten Produktplan auswählt (Auswahlfelder), möchte ich die aktuelle Benutzer-ID und ausgewählte Produkt-ID in der Tabelle userproducts Aber aus irgendeinem Grund genannt beitreten gespeichert werden könnte ich nicht speichern die Daten, ich habe keine Ahnung, wo ich falsch liege, jede Hilfe geschätzt, danke.Wie Controller und Ansichten für has_many zu schaffen und durch Beziehung in Ruby on Rails

Modelle:

class User < ActiveRecord::Base 
    has_many :userproducts 
    has_many :productplans, :through=>:userproducts 
end 

class productplan < ApplicationRecord 
    has_many :userproducts 
    has_many :users, :through => :userproducts 
end 

class Userproduct < ApplicationRecord 
    belongs_to :user 
    belongs_to :productplan 
end 

ProductPlan Controller:

class ProductPlanController < ApplicationController 
before_action :authenticate_user! 
def new 
    @user=User.new 
    end 
end 

def create 
    @user = User.create(user_params) 
    if @user.save 
    render :action => 'index' 
    else 
    render :action =>'new' 
    end 
private 
def user_params 
    params.require(:user).permit(:productplan_ids => []) 
end 
end 

Aufrufe: productplan/_form.html.erb

<%= form_for @user,:url=> productplan_index_path,:method => :post do 
|f|%> 
<%= f.collection_check_boxes :productplan_ids, ProductPlan.all, :id, 
:productplan_name %> 
<%= f.submit %> 
<% end %> 

Da es weniger Beispiele auf dem Controller und Ansichten sind in Bezug auf has_many durch Ich bin mir ziemlich sicher, dass ich viele Fehler darin habe. Auch wenn ich das Formular versuchen einreichen ich dieses Protokoll:

enterStarted POST "/Productplan" for 127.0.0.1 at 2017-11-28 11:08:29 -0600 
Processing by ProductPlanController#create as HTML 
Parameters 
{"utf8"=>"✓","authenticity_token"=> 
"mi9RwHCLPKItXai67t5iX0RYrDoE6TN9T 
iZzJFYELbKVDlHbhpeNmOC0q2gu1iXyWNaUqGSEsPrBEjcUSE2yYw==", "user"= > 
{"productsku_ids"=>["", "4", "7"]}, "commit"=>"Create User"} 
User Load (1.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 
ORDER BY "users"."id" ASC LIMIT $2 [["id", 3], ["LIMIT", 1]] 
ProductPlan Load (2.6ms) SELECT "productplans".* FROM "productplans" WHERE 
"productplans"."id" IN (4, 7) 
(0.5ms) BEGIN 
Provider Load (0.5ms) SELECT "providers".* FROM "providers" WHERE 
"providers"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]] 
CACHE Provider Load (0.0ms) SELECT "providers".* FROM "providers" WHERE 
"providers"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]] 
(0.6ms) ROLLBACK 
Rendering ups/new.html.erb within layouts/application 
ProductPlan Load (0.9ms) SELECT "productplans".* FROM "productplans" 
Rendered productplans/_form.html.erb (4.6ms) 
Rendered productplans/new.html.erb within layouts/application (6.4ms) 
Rendered _navbar.html.erb (0.7ms) 
Completed 200 OK in 191ms (Views: 102.1ms | ActiveRecord: 14.6ms) here 

Aus irgendeinem Grund es Rollbacks, auch muss ich auch den aktuellen Benutzer bekommen.

dependent_new GET /dependent/new(.:format)    dependent#new 
    dependent_create GET /dependent/create(.:format)   dependent#create 
     summary_root GET /summary/index(.:format)    summary#index 
      home_plans GET /home/plans(.:format)     home#plans 
       thanks GET /thanks(.:format)      charges#thanks 
    authenticated_root GET /         home#roothome 
    productplan_index GET /productplan(.:format)     productplan#index 
        POST /productplan(.:format)     productplan#create 
     new_productplan GET /productplan/new(.:format)    productplan#new 
    edit_productplan GET /productplan/:id/edit(.:format)  productplan#edit 
      productplan GET /productplan/:id(.:format)    productplan#show 
        PATCH /productplan/:id(.:format)    productplan#update 
        PUT /productplan/:id(.:format)    productplan#update 
        DELETE /productplan/:id(.:format)    productplan#destroy 
     userproducts GET /userproducts(.:format)    userproducts#index 
        POST /userproducts(.:format)    userproducts#create 
    new_userproduct GET /userproducts/new(.:format)   userproducts#new 
    edit_userproduct GET /userproducts/:id/edit(.:format)  userproducts#edit 
     userproduct GET /userproducts/:id(.:format)   userproducts#show 
        PATCH /userproducts/:id(.:format)   userproducts#update 
        PUT /userproducts/:id(.:format)   userproducts#update 
        DELETE /userproducts/:id(.:format)   userproducts#destroy 
       ups POST /ups(.:format)      ups#create 
       new_up GET /ups/new(.:format)     ups#new 
       root GET /         home#index 
    new_user_session GET /users/sign_in(.:format)    devise/sessions#new 
     user_session POST /users/sign_in(.:format)    devise/sessions#create 
destroy_user_session DELETE /users/sign_out(.:format)    devise/sessions#destroy 
    new_user_password GET /users/password/new(.:format)   devise/passwords#new 
    edit_user_password GET /users/password/edit(.:format)  devise/passwords#edit 
     user_password PATCH /users/password(.:format)    devise/passwords#update 
        PUT /users/password(.:format)    devise/passwords#update 
        POST /users/password(.:format)    devise/passwords#create 

SO modifizierte ich nach @jvillian zu gesagt, aber das Problem weiterhin besteht nach wie vor, hier ist mein neuer Code. Bitte beachten Sie, ich Benutzer Produkte ups umbenannt,

Modell:

class User < ActiveRecord::Base 
has_many :ups 
has_many :productplans, through: :ups 
end 

class productplan < ApplicationRecord 
has_many :ups 
has_many :users, :through => :ups 
end 

class Up < ApplicationRecord 
belongs_to :user 
belongs_to :productplan 
end 

Ups Controller:

class UpsController < ApplicationController 
before_action :authenticate_user! 

def create 
current_user.productplans<<Productplan.where(id: productplans_ids) 
render :action => 'index' 
end 

private 

def productplan_ids 
params.require(:up).permit(productplan_ids:[]) 
end 
end 

Aufrufe ups/_form.html.erb

<%= form_for :up,:url=> ups_path do |f| %> 
<%= f.collection_check_boxes :productplan_ids, Productplan.all, :id, 
:productplan_name %> 
<%= f.submit %> 
<% end %> 

Protokolle:

Started GET "/ups" for 127.0.0.1 at 2017-11-28 14:43:50 -0600 
Processing by UpsController#index as HTML 
User Load (1.6ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 
ORDER BY "users"."id" ASC LIMIT $2 [["id", 3], ["LIMIT", 1]] 
Rendering ups/index.html.erb within layouts/application 
Productplan Load (0.7ms) SELECT "productplans".* FROM "productplans" 
Rendered ups/_form.html.erb (42.5ms) 
Rendered ups/index.html.erb within layouts/application (47.7ms) 
Rendered _navbar.html.erb (0.9ms) 
Completed 200 OK in 347ms (Views: 235.0ms | ActiveRecord: 15.0ms) 


Started POST "/ups" for 127.0.0.1 at 2017-11-28 14:43:53 -0600 
Processing by UpsController#create as HTML 
Parameters: {"utf8"=>"✓", 
"authenticity_token"=>"g7lLydleU7J14G7N9avWSK87E4BbkPQ9sdL 
Q9X2bbSCMmEvSL0LiiLgJbR81o5Hls7UrEjv9d7o+5pTFY9Ly8Q==", "up"=> 
{"productplan_ids"=>["", "4"]}, "commit"=>"Save Up"} 
User Load (1.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 
ORDER BY "users"."id" ASC LIMIT $2 [["id", 3], ["LIMIT", 1]] 
Productplan Load (0.7ms) SELECT "productplans".* FROM "productplans" WHERE 
"productplans"."id" = $1 [["id", nil]] 
(0.4ms) BEGIN 
(0.3ms) COMMIT 
Rendering ups/index.html.erb within layouts/application 
Productplan Load (0.6ms) SELECT "productplans".* FROM "productplans" 
Rendered ups/_form.html.erb (4.9ms) 
Rendered ups/index.html.erb within layouts/application (7.9ms) 
Rendered _navbar.html.erb (1.0ms) 
Completed 200 OK in 201ms (Views: 183.4ms | ActiveRecord: 3.0ms) 

route.rb

devise_scope :user do 
# write all your routes inside this block 
resources :productplan 
resources :ups 
end 

Es gibt immer noch, wie in der Tabelle Ups, kein Fehler eingefügt keine Daten vorhanden sind. Obwohl laut Protokolldatei kein Rollback erfolgt, bleibt das Problem bestehen.

+1

Ihre form_for URL scheint falsch '<% = form_for @user,: url => productplan_index_path ', es sollte die create Aktion sein, nicht die Indexaktion – xeon131

+1

Warum hat Ihr ProductPlanController Methoden für User resource. Es sollte ein Controller für ProductPlan sein. Es macht keinen Sinn für mich –

+0

Ich fürchte, dieser Code ist zu kaputt, um zu beheben. – jvillian

Antwort

1

UPDATE: NACH CODE VERÄNDERUNGEN VON OP

Viel näher!

Wie Sie hier sehen können:

Productplan Load (0.7ms) SELECT "productplans".* FROM "productplans" WHERE "productplans"."id" = $1 [["id", nil]] 

wir nicht productplan_ids ganz recht bekommen hat (wie durch nil angegeben). Wenn in der Konsole, die Sie tun:

> params = ActionController::Parameters.new(up: {productplan_ids: ["","4"]}) 
> params.require(:up).permit(productplan_ids: []) 
=> {"productplan_ids"=>["", "4"]} 

Sie können sehen, dass die productplan_ids Verfahren kehrt ein hash (na ja, nicht ganz, aber nahe genug für jetzt). Aber Sie wollen den Wert für den Schlüssel :productplan_ids.Also, versuchen Sie:

def productplan_ids 
    params.require(:up)[:productplan_ids] 
end 

Welche sollten Sie geben:

> params.require(:up)[:productplan_ids] 
=> ["", "4"] 

die array Sie suchen.

ORIGINAL ANTWORT

ich eine Schaukel an diese zu übernehmen werde, aber es wird schwer sein.

Okay, nehmen wir an:

  • Sie ein angemeldeter Benutzer, die durch current_user in Ihrer create Aktion verfügbar ist (es sieht aus wie Sie verwenden Entwickeln?)
  • Sie haben bereits Ihre ProductPlans
  • In routes.rb haben Sie resources :user_products (nicht userproducts, siehe weiter unten beachten ...)

Ihre form_for sollte wie folgt aussehen:

<%= form_for :user_product, user_products_path do |f| %> 
    <%= f.collection_check_boxes :product_plan_ids, ProductPlan.all, :id, :product_plan_name %> 
    <%= f.submit %> 
<% end %> 

Hinweis: Sie das Symbol :user_product statt die Instanz-Variable @user, weil Sie keine Formularfelder auf @user stützen können.

Hinweis: Ein Formular führt automatisch eine post aus, sodass Sie method nicht angeben müssen.

Dann UserProductsController (nicht ProductPlanController da Sie ein Erstellen oder mehr user_products nicht product_plans) sollte in etwa so aussehen:

class UserProductsController < ApplicationController 

    def create 
    current_user.product_plans << ProductPlan.where(id: product_plan_ids) 
    render action: some_success_condition ? 'index' : 'new' 
    end 

    private 

    def product_plan_ids 
    params.require(:user_product).permit(product_plan_ids: []) 
    end 

end 

Hinweis: Sie wahrscheinlich nicht brauchen eine new Aktion, weil Sie nicht tun muss wirklich alles instanziieren (zumindest nicht basierend auf irgendetwas, was Sie gezeigt haben).

Hinweis: Sie müssen herausfinden, was some_success_condition ist. Aber es ist sicherlich nicht @user.save. Weil Sie user_products erstellen, kein user.

Auch Sie sagen:

params.require(:user).permit(:productplan_ids => []) 

Aber Ihre params sind:

{ 
    ..., 
    "user"=> { 
    "productsku_ids"=>["", "4", "7"] 
    }, 
    "commit"=>"Create User" 
} 

Sie erlauben productplan_ids (sollte product_plan_ids sein), aber haben productsku_ids (sollte product_sku_ids sein) in Ihrem params.

Einige andere Dinge:

Sie durch die ruby style guide lesen sollten Ihre Benennung korrekt zu erhalten.

Klassennamen sollten CamelCase sein. Also, ProductPlan, nicht Productplan.

Symbole und Variablen sollten SnakeCase sein. Also,: user_products, nicht: userproducts.

Controller-Namen sollten Plural sein, nicht Singular, wenn sie ressourcenorientiert sind. Also, ProductPlansController, nicht ProductPlanController. (Ich nehme an, Sie haben alle üblichen RESTful Aktionen für ProductPlan, wie new, create, edit, update, etc.)

UND, es ist in diesen Tagen konventionelleren through: :user_products als :through => :user_products zu tun.

So:

class User < ActiveRecord::Base 
    has_many :user_products 
    has_many :product_plans, through: :user_products 
end 

class ProductPlan < ApplicationRecord 
    has_many :user_products 
    has_many :users, through: :user_products 
end 

class UserProduct < ApplicationRecord 
    belongs_to :user 
    belongs_to :product_plan 
end 
Auch

, haben Sie eine Reihe von fehlangepassten def ... end Aussagen:

class ProductPlanController < ApplicationController 
    before_action :authenticate_user! 

    def new 
     @user=User.new 
    end 
    end # <= extra 'end' here 

    def create 
    @user = User.create(user_params) 
    if @user.save 
     render :action => 'index' 
    else 
     render :action =>'new' 
    end 
    # <= missing 'end' here 

    private 

    def user_params 
    params.require(:user).permit(:productplan_ids => []) 
    end 

end 

Ich gehe davon aus, dass irgendeine Art von copy-paste Fehler

Ich habe keine Idee, warum Sie tun:

def create 
    @user = User.create(user_params) 
    if @user.save 
    render :action => 'index' 
    else 
    render :action =>'new' 
    end 
end 

In Ihrem ProductPlansController. Es ist ProductPlansController. Es sollte ein ProductPlan, kein User erstellen.

+0

Hallo, Vielen Dank für die Post, ich werde das definitiv versuchen, auch FYI, ich habe Namensfehler, weil ich von meinem ursprünglichen Code bearbeitet habe, da die Namings kompliziert sind und ich niemanden verwechseln wollte, zum Beispiel ProductPlan ist eigentlich Productsku in meinem ursprünglichen code.but thanks so viel werde ich versuchen, und zurück zu dir.Tiere. –

+0

Am Ende arbeiten für Sie? Irgendwelche Probleme? – jvillian

+1

Ok, also habe ich getan, was du gesagt hast, habe einen neuen Controller erstellt und den Code so weit wie möglich geputzt, aber es gibt immer noch kein Einfügen von Daten in die Join-Tabelle. Ich werde bald den neuen Code posten –

Verwandte Themen