I am creating a rails web app with a many-to-many through model. The application is to allow users to populate their dashboard with a number of pre-defined "widgets". So I have a table of users (created and managed by devise) and a table of widgets. All good. So to manage the through bit, I have a table of "subscriptons". Here are my models:
class Subscription < ActiveRecord::Base
belongs_to :user
belongs_to :widget
validates_uniqueness_of :user_id, scope: :widget_id
end
class User < ActiveRecord::Base
has_many :subscriptions
has_many :widgets, through: :subscriptions
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
class Widget < ActiveRecord::Base
has_many :subscriptions
has_many :users, through: :subscriptions
end
However, I don't really understand how to create the subscriptions. I would ideally like the create form to just have a selector to choose from all available widgets and then user the current user:id
but I am not sure how this would work, here is my controller:
def new
@subscription = Subscription.new
end
def create
@user = current_user
@subscription = @user.subscriptions.build(subscription_params)
respond_to do |format|
if @subscription.save
format.html { redirect_to @subscription, notice: 'subscription was successfully created.' }
format.json { render :show, status: :created, location: @subscription }
else
format.html { render :new }
format.json { render json: @subscription.errors, status: :unprocessable_entity }
end
end
end
I would really appreciate a nudge in the right direction, as I can't understand how this is done from the official docs and haven't found any good tutorials relating to this.
Assuming you don't have any other attributes on subscriptions you can use the widget_ids=
method that your has_many
creates on user
Controller
class UserSubscriptionsController
def edit
@user = current_user
end
def update
@user = current_user
if @user.update(user_subscription_params)
redirect_to @user, notice: "Subscriptions updated"
else
render :edit
end
end
private
def user_subscription_params
params.require(:user).permit(widget_ids: [])
end
end
View
<%= form_for @user, url: user_subscription_path, method: :patch do |f| %>
<%= f.collection_check_boxes :widget_ids, Widget.all, :id, :name %>
<%= f.submit %>
<% end %>
The routes in my example would have
resource :user_subscription, only: [:edit, :update]
But obviously you can amend based on what you want your routes to be. Rails will automatically create the subscriptions when updating the user.
You could instead just use the collection_check_boxes
when editing a user normally if you wanted. There is also collection_select
You can save data like this using subscription form.
= form_for @subscription do |f|
= f.select :widget_id, options_from_collection_for_select(Widget.all, "id", "title"), {}, {:class => "form-control select" }
= f.hidden_field :user_id, :value => current_user.id
#other subscription fields
= f.submit
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.