Sorry for my English
I have a create many to many association between articles and categories
this is my article model
class Article < ActiveRecord::Base
has_many :categorizations
has_many :categories, through: :categorizations
end
this is my category model
class category < ActiveRecord::Base
has_many :categorizations
has_many :articles, through: :categorizations
end
in this my categorization model
class Categorizations < ActiveRecord::Base
belongs_to :article
belongs_to :category
end
then I have create the categories names in the Seed file
but I try to get the categories in a select but I get this Error
undefined method category_id' for <%= f.collection_select :category_id, Category.all, :id, :name, :include_blank => true %>
Just change <%= f.collection_select :category_id, Category.all, :id, :name, :include_blank => true %> to <%= f.collection_select :category_ids, Category.all, :id, :name, :include_blank => true %>
Related
When I add a new Book to my Library, I want to be able to specify what Shelves (note: "Shelf" is the term I used in my app for the model that groups Books together within a Library; a better name for this model would have been Category or Genre, but I was stupid) in that Library it should belong to. Right now, I'm able to add a Book to my Library, but I'm having issues with the Shelves. I'm pretty new at learning Rails and I'd appreciate any help.
Models
user.rb:
class User < ActiveRecord::Base
has_one :library, dependent: :destroy
...
end
library.rb:
class Library < ActiveRecord::Base
belongs_to :user
has_many :shelves, dependent: :destroy
has_many :catalogs, dependent: :destroy
has_many :books, :through => :catalogs, dependent: :destroy
...
end
book.rb:
class Book < ActiveRecord::Base
has_many :catalogs, dependent: :destroy
has_many :libraries, :through => :catalogs, dependent: :destroy
has_many :bookshelves, dependent: :destroy
has_many :shelves, :through => :bookshelves, dependent: :destroy
...
end
catalog.rb:
class Catalog < ActiveRecord::Base
belongs_to :book
belongs_to :library
end
shelf.rb:
class Shelf < ActiveRecord::Base
belongs_to :library
has_many :bookshelves, dependent: :destroy
has_many :books, :through => :bookshelves, dependent: :destroy
...
end
bookshelf.rb
class Bookshelf < ActiveRecord::Base
belongs_to :book
belongs_to :shelf
end
Controller
books_controller.rb
class BooksController < ApplicationController
...
def create
#book = Book.new(book_params)
#library = current_user.library
if #book.save
#book.catalogs.create(:library_id => #library.id)
flash[:success] = "Book added to library!"
redirect_to current_user
else
render 'current_user'
end
end
...
private
def book_params
params.require(:book).permit(:title, :author, :publisher, :isbn)
end
...
end
View
_book_form.html.erb:
<%= form_for(#book) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="field">
<%= f.text_field :title, placeholder: "Book Title" %>
<%= f.text_field :author, placeholder: "Author" %>
<%= f.text_field :publisher, placeholder: "Publisher" %>
<%= f.text_field :isbn, placeholder: "ISBN" %>
<%= f.fields_for :catalogs do |ff| %>
<%= ff.hidden_field :library_id %>
<% end %>
<%= f.fields_for :bookshelves do |ff| %>
<%= ff.collection_select :shelf_ids, current_user.library.shelves.all.collect {|x| [x.name, x.id]}, {}, multiple: true %>
<% end %>
</div>
<%= f.submit "Add Book to Library", class: "btn btn-primary" %>
<% end %>
In your book_params method, you don't have shelf_ids listed. So it won't be passed into the .new method and thus it won't be saved. Since you wan't multiple ids, you want to do this:
def book_params
params.require(:book).permit(:title, :author, :publisher, :isbn, shelf_ids: [])
end
That way, the controller knows it's an array and not just a single value.
Oh, and btw, shelf_ids and any other array values like that must be at the end or it will throw an error.
Edit:
Also change this part of code:
<%= f.fields_for :bookshelves do |ff| %>
<%= ff.collection_select :shelf_ids, current_user.library.shelves.all.collect {|x| [x.name, x.id]}, {}, multiple: true %>
<% end %>
to this:
<%= f.collection_select :shelf_ids, current_user.library.shelves.all.collect {|x| [x.name, x.id]}, {}, multiple: true %>
You don't need to worry about the through part of the association. Just set up the has_many part and it'll work.
I have a problem that's really confusing me.
I have four models, a Workout model, an Exercise model, a workout_exercise join model, and a workout_exercise_set model.
I can add exercises to workouts through the workout_exercises join table. Now I'm trying to add sets to exercises in workouts, which is what the workout_exercises_sets table is for.
Here's an example.
Workout
Exercise 1
Set 1
Set 2
Set 3
Exercise 2
Set 1
Set 2
Set 3
Exercise 3
etc.
In workouts/edit.html.erb I have a form where I can see all the exercises in the workout, and edit the number of sets by using form_for and fields_for, but when I try to update an exercise or the entire workout I get a MassAssignmentSecurity::Error in WorkoutsController#update that says Can't mass-assign protected attributes: workout_exercise_sets. I can't figure out how to get past this. I know I'm editing a workout, but I'm not trying to write to a field called workout_exercise_sets, so I'm really confused here. I really appreciate any guidance. All relevant code is below.
workout/edit.html.erb:
<%= form_for(#workout) do |f| %>
<%= f.label :name %><br />
<%= f.text_field :name %><br />
<%= f.label :description %><br>
<%= f.text_area :description %></br>
<%= f.fields_for :workout_exercises do |s| %>
<%= s.object.exercise.name %></b>
<%= s.fields_for :workout_exercise_sets do |set| %>
<%= set.label :set_number %>:
<%= set.number_field :set_number %>
<%= set.label :reps %>:
<%= set.number_field :repetitions %>
<%= set.label :rest_time %>(seconds):
<%= set.number_field :rest_time %>
<%= set.submit %>
<% end %>
<%= s.hidden_field :_destroy %>
<%= link_to "Remove exercise?", '#', class: "remove_fields" %>
<% end %>
<%= f.submit %>
<% end %>
Here is the workout model:
class Workout < ActiveRecord::Base
attr_accessible :name, :exercises_attributes, :workout_exercises_attributes, :exercise_order, :description
has_many :workout_exercises, dependent: :destroy, :order => "exercise_order DESC"
has_many :exercises, through: :workout_exercises
accepts_nested_attributes_for :exercises
accepts_nested_attributes_for :workout_exercises, allow_destroy: :true
end
Here is the exercise model:
class Exercise < ActiveRecord::Base
attr_accessible :name, :description
has_many :workout_exercises
has_many :workouts, through: :workout_exercises
validates :name, uniqueness: :true, presence: :true
validates :description, uniqueness: :true, presence: :true
end
Here is the workout_exercise model:
class WorkoutExercise < ActiveRecord::Base
attr_accessible :exercise_id, :workout_id
belongs_to :exercise
belongs_to :workout
has_many :workout_exercise_sets, dependent: :destroy
accepts_nested_attributes_for :workout_exercise_sets, allow_destroy: :true
end
and finally, here is the workout_exercise_sets model:
class WorkoutExerciseSet < ActiveRecord::Base
attr_accessible :repetitions, :rest_time, :set_number, :workout_exercise_id
belongs_to :workout_exercise
end
And for good measure, here is a diagram of the DB:
I think in your workout_excercise.rb file, you should add :workout_exercise_sets_attributes to your attr_accessible list.
class WorkoutExercise < ActiveRecord::Base
attr_accessible :exercise_id, :workout_id, :workout_exercise_sets_attributes
belongs_to :exercise
belongs_to :workout
has_many :workout_exercise_sets, dependent: :destroy
accepts_nested_attributes_for :workout_exercise_sets, allow_destroy: :true
end
Given the following Model, Relationship & Edit Form
class User < ActiveRecord::Base
has_many :relationships, foreign_key: "follower_id", dependent: :destroy
has_many :followed_users, through: :relationships, source: :followed
has_many :reverse_relationships, foreign_key: "followed_id",
class_name: "Relationship",
dependent: :destroy
has_many :followers, through: :reverse_relationships, source: :follower
end
<%= form_for(#topic) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :Followers %>
<%= f.fields_for :relationships do |builder| %>
<%= f.collection_select :follower_id, User.all( order: "name"), :id, :name, include_blank: true %>
<% end %>
<%= f.submit "Save Changes" %></div>
<% end %>
class Relationship < ActiveRecord::Base
attr_accessible :followed_id
belongs_to :follower, class_name: "User"
belongs_to :followed, class_name: "User"
validates :follower_id, presence: true
validates :followed_id, presence: true
end
In this case, the fields for relationships appear in the edit form for a given user. Thus, they can manage all of their followers. But the problem is, on the edit page, the users show up in the order they were added. Is there any way to sort them such that they appear alphabetically by name, despite the fact that the :relationships association has only an id?
It's the third day I'm crushing on Active Admin.
I have #survey that has_many :questions and each question has_many :answers - they are actually variants users can choose from.
But still I cant put it to work, it just doesn't create anything deeper then 1 level:
even the form works properly, but nothing is created.
I have the following clases Course->Sections->Lessons.
I did the following:
form do |f|
f.inputs "Details" do
f.input :instructor, :as => :select
f.input :title
f.input :name
f.input :price
f.input :discount
f.input :slug
f.inputs "Sections" do
f.has_many :sections, :header=>"" do |section|
section.input :name
section.input :position
if section.object.id
section.input :_destroy, :as=>:boolean, :required => false, :label=>'Remove'
end
section.has_many :lessons, :header=>"Lessons" do |lesson|
lesson.input :title
lesson.input :position
lesson.input :duration
lesson.input :_destroy, :as=>:boolean, :required => false, :label=>'Remove'
end
end
end
end
f.buttons
end
My models are as follow:
class Course < ActiveRecord::Base
has_many :sections, :dependent => :delete_all
accepts_nested_attributes_for :sections, :allow_destroy => true
attr_accessible :sections_attributes
....
class Section < ActiveRecord::Base
belongs_to :course
has_many :lessons, :dependent => :delete_all
attr_accessible :course_id, :name, :position
accepts_nested_attributes_for :lessons, :allow_destroy => true
attr_accessible :lessons_attributes
....
class Lesson < ActiveRecord::Base
belongs_to :section
attr_accessible :duration, :position, :section_id, :title
....
And it works great! I don't know what happens if I go more levels deeper.
I have the following Models:
class Topic < ActiveRecord::Base
has_many :posts, :dependent => :destroy
attr_accessible :name, :post_id
end
class Post < ActiveRecord::Base
belongs_to :topic, :touch => true
has_many :comments, :dependent => destroy
accepts_nested_attributes_for :topic, :comments
attr_accessible :name, :title, :content, :topic, :topic_attributes
end
class Comment < ActiveRecord::Base
belongs_to :Post
end
Is this simple form valid? Can I access 2 nested Models at the same time?
simple_form_for #post do |f|
f.simple_fields_for :topic do |topic_form|
topic_form.input :name
end
f.simple_fields_for :comment do |comment_form|
comment_form.input :text
end
end
Thanks
Try this
simple_form_for #post do |f|
f.simple_fields_for #post.topic do |topic_form|
topic_form.input :name
end
f.simple_fields_for #post.comments do |comment_form|
comment_form.input :text
end
end