I have the following setup in my rails app:
A user registers and he chooses from a set of check boxes for Music Styles.
The Music Styles are only 4 right now but should be extendable. I'd like to have a list of MusicStyles that I can extend and change easily.
My approach would be to create a model 'MusicStyles' and a model 'UserMusicStyles' and then use a has_many_through association similar to:
class User < ActiveRecord::Base
has_many :user_music_styles
has_many :music_styles, :through => :user_music_styles
end
class UserMusicStyle < ActiveRecord::Base
belongs_to :user
belongs_to :music_style
end
class MusicStyle < ActiveRecord::Base
has_many :music_styles
has_many :users, :through => :user_music_styles
end
Now, during registration I would do something like MusicStyle.all.each do |m| ... to display the checkboxes but how do I save it to the database correctly in the user controller?
Any help much appreciated!
You can do it like this:
<%= form_for #user do |f| %>
<!-- User stuff -->
...
<% MusicStyle.all.each do |m| %>
<%= check_box_tag('user[music_style_ids][]', m.id, #user.music_styles.include?(m)) %>
<% end %>
<%= f.submit 'Save' %>
<% end %>
Related
I have a User, a Wiki, and a Collaborator model:
class User < ActiveRecord::Base
has_many :wikis
has_many :collaborators
end
class Wiki < ActiveRecord::Base
has_many :wikis
has_many :collaborators
end
class Collaborator < ActiveRecord::Base
belongs_to :user
belongs_to :wiki
end
When I am editing a Wiki's collaborators I would like the form to look something like this:
My problem is that I cannot figure out how to construct the form. I thought the following would work but <% form_for :collaborator do |f|%> doesn't result in anything being included in the resulting page.
<% form_for :collaborator do |f|%>
<% possible_collaborators.each do |user| %>
<%= check_box_tag 'wiki[collaborator_ids][]', user.id, wiki.collaborators.include?(user) %>
<%= user.name %>
<br />
<% end %>
<%= f.submit %>
<% end %>
As you didn't post your controller code I can't be entierly sure what you are trying to accomplish, but I think you are missing out on the accepts_nested_attributes_for (docs, tutorial with controller code).
Furthermore I can only recommend you the use simple_forms or formtastic as those gems do a good job when it comes to complex forms and help you a lot with the basic use cases.
I'm trying to build a rather complex nested form in rails and am stuck.
Basically, I have three models - Applicant, DataPoint, ApplicantDataPointValue .
The user can create a new DataPoint, give it a name ("gender" etc.) select it's type ("string","integer" etc.). The type determines what column the data will eventually be saved in in the ApplicantDataPointValue table.
I then want the user, when they're creating a new Applicant, to be able to add a value for each DataPoint into the ApplicantDataPointValue table
My models look like the following:
Applicant:
class Applicant < ActiveRecord::Base
has_many :applicant_data_point_values, dependent: :destroy
has_many :data_points, :through => :applicant_data_point_values
accepts_nested_attributes_for :data_points
accepts_nested_attributes_for :applicant_data_point_values
attr_accessible :data_points_attributes, :applicant_data_point_values_attributes
end
DataPoint:
class DataPoint < ActiveRecord::Base
has_many :applicant_data_point_values
has_many :applicants, :through => :applicant_data_point_values
accepts_nested_attributes_for :applicant_data_point_values
end
ApplicantDataPointValue:
class ApplicantDataPointValue < ActiveRecord::Base
belongs_to :data_point
belongs_to :applicant
end
But I'm at a loss to what to do in the 'new' and 'create' sections of my controller or how to construct the form.
Any insight would be greatly appreciated.
From what I understand, the form for the User will also have multiple ApplicantDataPointValue fields. (but that form won't allow creating of new DataPoint fields, right?)
In the controller new action, you'll want to set up your model with associated data point values:
def new
#user = User.new
DataPoint.all.each do |data_point|
applicant_data_point_value = #user.applicant_data_point_values.build
applicant_data_point_value.data_point = data_point
end
end
And then, display a text box for each data point value.
<%= form_for #user do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
<% #user.applicant_data_point_values.each do |data_point_value| %>
<%= f.fields_for :applicant_data_point_values, data_point_value do |fields| %>
<%= fields.label :value, data_point_value.data_point.type %>
<%= fields.text_field :value %>
<% end %>
<% end %>
Reference: http://railscasts.com/episodes/196-nested-model-form-part-1
I have these models:
class Order < ActiveRecord::Base
has_many :order_lines
has_many :prizes, :through => :order_lines
accepts_nested_attributes_for :order_lines
end
class Prize < ActiveRecord::Base
has_many :order_lines
end
class OrderLine < ActiveRecord::Base
belongs_to :order
belongs_to :prize
end
I would like a nested form in the order form that displays every prize with a text box next to it where the user can enter pieces (eg. the amount to order). When the form is submitted the create action should create the order_lines accordingly. I can't find a solution anywhere.
First of all in the Order model use accepts_nested_attributes_for :prizes, instead of what you have.
After that it's easy, just add a form in the view (there's no additional step controller)
<%= form_for #order do |order_form| %>
..
<%= order_form.fields_for :prizes do |prizes_form| %>
<%= prizes_form.text_field :piece %>
..
<% end %>
..
<% end %>
This is straight from the documentation... You should definitely check that first.
I have a one-to-one relationship between user and goal. I want to build a form that shows the goal of a user. The problem is that my code only works when the user already has a goal defined. The text field is not rendered when no goal is present.
<%= user_builder.fields_for :goal do |goal_builder| %>
<%= goal_builder.text_field :goal %>
<% end %>
Does Rails provide an easy way to do this?
This is how I would do it :
class User < ActiveRecord::Base
has_one :goal
accepts_nested_attributes_for :goal
after_initialize do
self.goal ||= self.build_goal()
end
end
You can do this very easily with accepts_nested_attributes_for.
In the view, as you had:
<%= user_builder.fields_for :goal do |goal_builder| %>
<%= goal_builder.text_field :goal %>
<% end %>
In the User model:
class User < ActiveRecord::Base
has_one :goal # or belongs_to, depending on how you set up your tables
accepts_nested_attributes_for :goal
end
See the documentation on nested attributes, and the form_for method for more information.
I have built a ruby on rails app that lets users track their workouts. User has_many workouts. In addition, a User can create a box (gym) if they are a gym owner. The purpose is to filter activity of users such that they can only see information related to their gym. Users can then specify if they are a member of that box through a Membership model. The Membership table collects #box.id and current_user.id in the membership.box_id and user.id columns respectively.
The user associates through the following form in the /views/boxes/show.html.erb view:
<% remote_form_for Membership.new do |f| %>
<%= f.hidden_field :box_id, :value => #box.id %>
<%= f.hidden_field :user_id, :value => current_user.id %>
<%= submit_tag "I am a member of this box" , :class => '' %>
<% end %>
I then display, in the box show page all the users who are members of that box.
<% #box.users.each do |user| %>
<%= link_to (user.username), user %><br/>
<% end %>
I am trying to restrict the form to only users who are not already members of that box but I am not sure how to write the <% unless ... %> statement.
Here are the rest of the associations:
User
class User < ActiveRecord::Base
has_many :boxes
has_many :workouts, :dependent => :destroy
end
Workout
class Workout < ActiveRecord::Base
belongs_to :user
belongs_to :box
end
Box
class Box < ActiveRecord::Base
belongs_to :user
has_many :users, :through => :memberships
has_many :workouts, :through => :users
has_many :memberships
end
Membership
class Membership < ActiveRecord::Base
belongs_to :user
belongs_to :box
end
# Membership model
named_scope :for_box, lambda {|box| {:conditions => {:box_id => box.id}}}
# User model
has_many :memberships
def member_of_box?(box)
!memberships.for_box(box).blank?
end
# View
<% unless current_user.member_of_box?(box) %>
# Show the form
<% end %>
Disclaimer: The code is not tested. It might need minor alterations.