Attempting to add data to a join table of scrapbook_entries which has_one :scrapbook and has_one :recipe.
:recipe and :scrapbook already exist. I am trying to add them to link them with the scrapbook_entries table.
form_for adding to scrapbook_entries table:
<%= form_for(#scrapbook_entry, :url => scrapbook_entries_path(params[:id])) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="field">
<%=f.select(:scrapbook_id, current_user.scrapbooks.collect {|p| [ p.name, p.id ] }, {prompt: 'Select Scrapbook...'})%>
<%= f.hidden_field :recipe_id, :value => #recipe.id %>
</div>
<%= f.submit "Save", class: "btn btn-large btn-primary" %>
<% end %>
scrapbook_entries_controller:
def create
#recipe = Recipe.find(params[:scrapbook_entry][:recipe_id])
#scrapbook = current_user.scrapbooks.find(params[:scrapbook_entry][:scrapbook_id])
#entry = #scrapbook.scrapbook_entries.build(scrapbook: #scrapbook)
if #entry.save
flash[:success] = "Added '#{#recipe.name}' to scrapbook '#{#scrapbook.name}'"
else
flash[:error] = "Could not add to scrapbook"
end
redirect_to #recipe
end
scrapbook.rb
has_many :recipes, through: :scrapbook_entries
has_many :scrapbook_entries
recipe.rb
has_many :scrapbooks, through: :scrapbook_entries
scrapbook_entry.rb
has_one :recipe
has_one :scrapbook
On submitting the form to the controller I am getting a error:
can't write unknown attribute `scrapbook_entry_id'
Can anyone tell me what I am doing wrong?
Update:
schema.rb
create_table "scrapbook_entries", force: true do |t|
t.integer "scrapbook_id"
t.integer "recipe_id"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "user_id"
end
Your scrapbook_entr.rb should contain
belongs_to :recipe
belongs_to :scrapbook
and not has_one!
You always use belongs_to when your table contains a foreign key to another table, which in this case definitely is the case!
Related
I'm getting a weird error with a "New Comment" form.
First, when I submit the comment- I get a popup to save a file (there is no file to save).
However, the comment is not creating because my app thinks that one of the comment's attributes must exist, when it doesn't need to.
This is my error when submitting:
errors: ["Parent must exist"]
No template found for Events::CommentsController#create, rendering head :no_content
(However, when you submit a comment with a head, it works as expected)
comments_controller.rb
def create
#comment = #commentable.comments.build(comment_params)
if #comment.save
flash[:success] = "Your comment was successfully saved."
redirect_to #commentable
else
puts "errors: #{#comment.errors.full_messages}"
flash[:danger] = "Uh Oh"
end
end
schema.rb
create_table "comments", force: :cascade do |t|
t.integer "parent_id"
t.string "commentable_type"
t.bigint "commentable_id"
end
comment.rb
class Comment < ApplicationRecord
belongs_to :commentable, polymorphic: true
belongs_to :parent, class_name: "Comment"
has_many :children, class_name: "Comment", foreign_key: :parent_id, dependent: :destroy
end
new_comment_form.html.erb
<%= form_for [commentable, Comment.new] do |f| %>
<div class="form-group">
<div class="col-6">
<%= f.text_area :body, class: "form-control", placeholder: "", style: "height: 200px;" %>
</div>
</div>
<div class="form-group">
<div class="col-3">
<%= f.submit "add comment", class: "btn btn-light ", id: "submit-comment" %>
</div>
</div>
<% end %>
Rails 5 makes belongs_to association required by default - there's a great article about it here.
Basically, you just need to mark your belongs_to relationship as optional:
belongs_to :parent, class_name: "Comment", optional: true
Is there a way to update a field relative to a many-to-many associations via form_for?
Theses are my models:
class Grad < ActiveRecord::Base
belongs_to :school
has_many :grad_courses
has_many :courses, through: :grad_courses
accepts_nested_attributes_for :grad_courses, :courses
end
class Course < ActiveRecord::Base
belongs_to :school
has_many :grad_courses
has_many :grads, through: :grad_courses
end
class GradCourse < ActiveRecord::Base
belongs_to :grad
belongs_to :course
end
Here is the many-to-many migration with the extra property (semester):
create_table "grad_courses", force: :cascade do |t|
t.integer "grad_id"
t.integer "course_id"
t.integer "semester"
t.datetime "created_at"
t.datetime "updated_at"
end
What i'm trying to do is add and update the relations with the semester information dynamically with a form collection set (using form_for and chosen).
<%= form_for #grad, html: {class: "form-horizontal"} do |f| %>
...
<% (1..#grad.max).each do |semester| %>
<div class="form-group">
<%= f.label :course_ids, "#{semester}º semestre", class: "col-sm-2 control-label" %>
<div class="col-sm-10">
<%= f.collection_select :course_ids, #courses, :id, :name, {include_blank: true}, {multiple: true, :class=>'chosen-select form-control'} %>
</div>
</div>
<% end %>
...
<% end %>
This way, it is creating and updating the grad_courses, but without the semester.
I've tried lot of things, but didn't had success.
I'm able to manage the semester's info directly, like in this post: http://stackoverflow.com/questions/2168442/many-to-many-relationship-with-the-same-model-in-rails#=
I could pass an array with a hidden field, and manage the form manually, but it would take too much work, so I was wondering if there is an easy way to do this.
Something like :grad_course[:course_id][:semester] in :grad params? Is it possible?
the grad_course_controller:
def update
respond_to do |format|
if #grad.update(grad_params)
format.html { redirect_to #grad, notice: 'Cursos adicionados com sucesso' }
else
format.html { render :edit }
end
end
end
private
def set_grad
#grad = Grad.find(params[:id])
end
def set_courses
#courses = Course.where(school_id: #grad.school_id)
#gc = GradCourse.where(grad_id: #grad.id)
end
list through.
def grad_params
params.require(:grad).permit(:name, :min, :max, :school_id, course_ids: [] )
end
Update
I've been trying to solve this using Peter's advices, so I tried nested_attributes and fields_for. But I'm having problems with it too.
I need one collection_sellect for each semester (from 1 to Grad.max number), where the options will be the courses available for that semester (#courses), and for the selected ones a grad_course relation needs to be created or updated.
The problem with field_for is that one field is generated for every grad_course relation, and since each field is related with the grad_course.id I`m not able to add new ones properly.
Here is one of the tries i've made with fields for:
<%= f.fields_for :grad_courses do |builder| %>
<p>
<%= builder.text_field :semester %><br />
<%= builder.collection_select :course_id, #courses, :id, :name, {include_blank: true}, {multiple: true, :class=>'chosen-select form-control'} %>
</p>
<% end %>
with these changes in the grad_controller:
def grad_params
params.require(:grad).permit(:name, :min, :max, :school_id, course_ids: [], grad_courses_attributes: [:id, :course_id, :grad_id, :semester ])
end
Have you tried to add the :course_ids on the permit list?
Like this:
def grad_params
params.require(:grad).permit(:name, :min, :max, :school_id, :course_ids)
end
I am trying to create a profile page where I can input "born_on". It will be using the
class CreateWineMakers < ActiveRecord::Migration
def change
create_table :wine_makers do |t|
t.string :name
t.date :born_on
t.text :nationality
t.text :profile
t.text :wine
t.integer :wine_list_id
t.timestamps
end
add_index :wine_makers, :wine_list_id
end
end
Here is my view file.
<%= simple_form_for WineMaker.new do |f| %>
<%= f.input :name %>
<%= f.input :profile %>
<%= f.input :wine %>
<%= f.input :born_on %>
<br/>
<%= f.submit "Create", :class => 'btn btn-primary' %>
<% end %>
The "born_on" is giving me error saying the method is not defined. I am confused since all other inputs are working except "born_on" and "nationality". Before, my "born_on" was named "birth_date", and I thought the naming convention was wrong and changed it to "born_on". Here is the controller.
class WineMakersController < ApplicationController
def new
#wine_maker = WineMaker.new
end
def create
#wine_maker = WineMaker.create(wine_maker_params)
redirect_to wine_list_path(#wine_list)
end
def show
end
private
def wine_maker_params
params.require(:wine_maker).permit(:name, :born_on, :nationality, :profile, :wine )
end
end
This seems like such an easy question that I couldn't find similar problems..
Thank you.
For my application, I have Users, who can Create Project Postings. On each Project Posting, they can make comments that I have made a Blogupdate model. I want users to be able to like Blogupdates made on each Project page.
So, I created a Bloglike model. But when I try to render a LIKE/UNLIKE button, I get the following error:
NoMethodError in Projects#blogs
undefined method `bloglikes_path'
Extracted source (around line #11):
11: <%= form_for(current_user.bloglikes.build(blogupdate_id: blogupdate.id)) do |f| %>
Question: As a note, I have not built up the controller for the actual create/destroy function in my bloglikes controller; but looking at my attached code below, does somebody know how I can resolve this error so the like/unfollow button renders?
schema.rb
create_table "bloglikes", :force => true do |t|
t.integer "user_id"
t.integer "blogupdate_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
add_index "bloglikes", ["blogupdate_id"], :name => "index_bloglikes_on_blogupdate_id"
add_index "bloglikes", ["user_id", "blogupdate_id"], :name => "index_bloglikes_on_user_id_and_blogupdate_id", :unique => true
add_index "bloglikes", ["user_id"], :name => "index_bloglikes_on_user_id"
user.rb
has_many :bloglikes, foreign_key: "user_id"
has_many :liked_blogupdates, through: :bloglikes, source: :blogupdate
blogupdate.rb
has_many :bloglikes, foreign_key: "blogupdate_id"
has_many :liked_by, through: :bloglikes, source: :user
def liking_blogupdate?(blogupdate)
bloglikes.find_by_blogupdate_id(blogupdate.id)
end
def like_blogupdate!(blogupdate)
bloglikes.create!(blogupdate_id: blogupdate.id)
end
def blogupdate_unlike!(blogupdate)
bloglikes.find_by_blogupdate_id(blogupdate.id).destroy
end
bloglike.rb
class Bloglike < ActiveRecord::Base
attr_accessible :blogupdate_id
belongs_to :user, foreign_key: "user_id"
belongs_to :blogupdate, foreign_key: "blogupdate_id"
end
projects_controller.rb
def blogs
#project = Project.find(params[:id])
#blogupdates = #project.blogupdates.newest.page(params[:blogupdates_page]).per_page(5)
end
views/projects/blogs.html.erb
<%= render 'blogs' %>
views/projects/_blogs.html.erb
<%= render #blogupdates %>
views/blogupdates/_blogupdates.html.erb
<%= blogupdate.liked_by.count %>
<% if current_user.liking_blogupdate?(blogupdate) %>
<%= form_for(current_user.bloglikes.find_by_blogupdate_id(blogupdate),
html: { method: :delete }) do |f| %>
<%= f.submit "UNLIKE", class: "btn btn-medium" %>
<% end %>
<% else %>
<%= form_for(current_user.bloglikes.build(blogupdate_id: blogupdate.id)) do |f| %>
<div><%= f.hidden_field :blogupdate_id %></div>
<%= f.submit "LIKE", class: "btn btn-medium btn-primary" %>
<% end %>
<% end %>
<p><%= raw blogupdate.content %></p>
UPDATE: As noted below by #Dan, I forgot to update the routes.rb file. I added "resources :bloglikes" and it worked now.
You didn't post your routes.rb file but I'd wager that is where the problem is at. An undefined method related to routes (e.g. bloglikes_path) typically indicates you've not defined the routes.
Add resources :bloglikes to your project's routes.rb file and see if that resolves the issue.
i can't insert to my database whats is my problem?
it's bowling game and i have two tables with name "Player" and "Result"
view
<%= form_for player_new_path(#player) do |f|%>
<div class="text_field">
<p>
<%= f.label "Spelare namn" %>
<%= f.text_field :name %>
</p>
<p>
<%= f.submit "Lägg till en spelare"%>
</p>
</div>
Controller
def create
#player = Player.new(params[:players])
if #player.save
redirect_to players_new_path
else
render :action => "new"
end
end
Not work :/
my model:
class Player < ActiveRecord::Base # attr_accessible :title, :body
belongs_to :result
end
and my migrations:
class CreatePlayers < ActiveRecord::Migration
def change
create_table :players do |t|
t.string "name"
t.references :results
t.timestamps
end
Check your params hash. I bet the key isn't 'players', it's probably 'player'.
#player = Player.new(params[:players]) should probably be #player = Player.new(params[:player]) (You are getting a single player as a param)
Otherwise, what error are you getting