I have a bug, that is driving me crazy for a few days now....I set up a many to many relationship between users (created by devise) and parks through table user_parks. When I want to create a new park with a certain user, I get the error message: "undefined method `user=' for # Did you mean? users= users". Unfortunately, I am not able to find the mistake in my code that prevents me from creating the relationship between user and parks.
Schema
create_table "parks", force: :cascade do |t|
t.text "name"
end
create_table "user_parks", force: :cascade do |t|
t.bigint "park_id"
t.bigint "user_id"
t.index ["park_id"], name: "index_user_parks_on_park_id"
t.index ["user_id"], name: "index_user_parks_on_user_id"
end
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.integer "role"
end
add_foreign_key "user_parks", "parks"
add_foreign_key "user_parks", "users"
end
models
class Park < ApplicationRecord
has_many :user_parks
has_many :users, :through => :user_parks
end
class UserPark < ApplicationRecord
belongs_to :park
belongs_to :user
end
class User < ApplicationRecord
has_many :user_parks
has_many :parks, :through => :user_parks
enum role: [:owner, :admin, :employee, :accountant]
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
end
Park policy
class ParkPolicy < ApplicationPolicy
class Scope < Scope
def resolve
if user.admin?
scope.where(user: user)
end
end
end
def index?
user.admin?
end
def new?
user.admin?
end
def create?
user.admin?
end
end
parks_controller
class ParksController < ApplicationController
skip_before_action :authenticate_user!
#create a new park
def new
@park = Park.new
authorize @park
end
def create
@user = current_user
@park = Park.new(park_params)
authorize @park
@park.user = @user
@park.save
redirect_to parks_path
end
#edit park
def edit
@park = Park.find(params[:id])
end
def update
@park = Park.find(params[:id])
@park = Park.update(park_params)
redirect_to parks_path
end
def index
@user = current_user
@parks = policy_scope(Park)
end
private
def park_params
params.require(:park).permit(:name)
end
end
new.html.erb (for park)
<%= simple_form_for ([@user, @park]) do |f|%>
<%= f.input :name %>
<%= f.submit "Add park", class: "btn btn-primary" %>
<% end %>
When I want to create a new park with a certain user, I get the error message: "undefined method `user=' for # Did you mean? users= users".
You have has many association. Instead of @user.park
you need to use @user.parks
The easiest way is to initialize park object before you initialize form
parks_controller
def new
@park = current_user.parks.build
authorize @park
end
def create
@park = current_user.parks.create(park_params)
redirect_to parks_path
end
new.html.erb (for park)
<%= simple_form_for(@park) do |f|%>
<%= f.input :name %>
<%= f.submit "Add park", class: "btn btn-primary" %>
<% end %>
you can check methods available for object with has many association here: docs