Self-Referential Association - Friending Feature in Rails - ruby-on-rails

I am trying to build a simple friending system for a basic social site. I just need my "Wag" link to trigger an action to favorite that current pet to a favorites page for the owner. I followed the RailsCast here to set everything up.
This is the path link I am trying to set up.
<% #pets.each do |pet| %>
<div>
<%= link_to "Wag", owner_friendships_path(friend_id: owner), method: :post %>
</div>
<% end %>
</div>
It should go here:
<ul>
<% for friendship in #owner.friendships %>
<li>
<%= friendship.friend.name %>
(<%= link_to "remove", friendship, method: :delete %>)
</li>
<% end %>
</ul>
<p><%= link_to "Find Puppy Pals", pets_path %></p>
Routes:
Rails.application.routes.draw do
devise_for :owners
resources :pets
resources :owners do
resources :pets, shallow: true
resources :friendships
end
root to: "pets#index"
end
The relevant schema looks like:
create_table "friendships", force: true do |t|
t.integer "owner_id"
t.integer "friend_id"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "owners", force: true do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
...(devise defaults)
t.datetime "created_at"
t.datetime "updated_at"
t.string "profile_photo"
end
My friendship controller:
class FriendshipsController < ApplicationController
def index
#friendships = Friendship.all
end
def show
#friendship = Friendship.find(params[:id])
end
def create
#friendship = current_owner.friendships.build(params[:friend_id])
if #friendship.save
flash[:notice] = "Added puppy pal."
redirect_to root_url
else
flash[:error] = "Oops, we couldn't save that puppy pal."
redirect_to root_url
end
end
def destroy
#friendship = current_owner.friendships.find(params[:id])
#friendship.destroy
flash[:notice] = "Removed puppy pal."
redirect_to root_url
end
end
Pets controller:
Class PetsController < ApplicationController
def index
#pets = Pet.order("RANDOM()").limit(1)
end
def new
#pet = Pet.new
end
def create
#pet = Pet.new(pet_params)
#pet.owner_id = current_owner.id if current_owner
if #pet.save
flash[:notice] = 'Your pet profile was saved!'
redirect_to pets_path
else
flash.now[:notice] = 'Your pet profile could not be saved.'
render :new
end
end
def show
#pet = Pet.find(params[:id])
end
def edit
#pet = Pet.find(params[:id])
end
def update
#pet = Pet.find(params[:id])
if #pet.update(pet_params)
redirect_to pets_path
else
render :edit
end
end
def destroy
#pet = Pet.find(params[:id])
if current_owner == #pet.owner
#pet.destroy
redirect_to pets_path
end
end
private
def pet_params
params.require(:pet).permit(:name, :breed, :age,
:color, :weight, :personality, :favorite_things, :owner_id, :profile_photo)
end
end
Pets Table:
create_table "pets", force: true do |t|
t.string "name"
t.string "breed"
t.integer "age"
t.integer "weight"
t.text "personality"
t.text "favorite_things"
t.integer "owner_id"
t.datetime "created_at"
t.datetime "updated_at"
t.string "profile_photo"
end
Owner Controller:
class OwnersController < ApplicationController
def show
#pet = Pet.find(params[:id])
end
def edit
#owner = Owner.find(params[:id])
end
end

You need to change this line:
<%= link_to "Wag", friendships_path(friend_id: owner), method: :post %>
to this:
<%= link_to "Wag", friendships_path(friend_id: pet.owner_id), method: :post %>
owner is never defined by itself. whatever you're calling (I guess it is owner_id based on your db model) needs to be called on the instance of pet in the block

Related

Making a to-do webapp and got such an error SQLite3::SQLException: no such column: tasks.list_id

Showing /home/arthur/Desktop/application/todo/app/views/tasks/index.html.erb where line #7 raised:SQLite3::SQLException: no such column: tasks.list_id
This error appears when I am trying to open the created list to add new tasks. I think the problem is the app can't get the id of the list I am trying to open. But I can't understand what's wrong. (new with ruby and rails). Do I need to add views or something else?
Task Controller
class TasksController < ApplicationController
helper_method :task, :list, :tasks
def create
task.save
redirect_to list_tasks_path(list)
end
def update
task.update task_params
redirect_to list_tasks_path(list)
end
def complete
task.complete
redirect_to list_tasks_path(list)
end
def destroy
task.destroy
redirect_to list_tasks_path(list)
end
private
delegate :tasks, to: :list, private: true
def task
#task ||= params[:id] ? list.tasks.find(params[:id]) : list.tasks.new(task_params)
end
def list
#list ||= List.find params[:list_id]
end
def task_params
params.require(:task).permit(:title, :completed)
end
end
and ListsController
class ListsController < ApplicationController
#helper_method :list, :lists
def index
#lists = List.order('created_at')
end
def new
#list = List.new
end
def create
#list = List.new list_params
#list.save
redirect_to lists_path
end
def edit
#list = List.find params[:id]
redirect_to lists_path
end
def update
#list = List.find params[:id]
#list.update list_params
redirect_to lists_path
end
def destroy
#list = List.find params[:id]
#list.destroy
redirect_to lists_path
end
private
def list_params
params.require(:list).permit(:title)
end
end
View Index.html.erb
<div class="col-md-12">
<h2>Tasks</h2>
<div class="buffer-top"><%= link_to "New Task", new_list_task_path(list), class: 'btn btn-primary' %></div>
<div class="buffer-top">
<% tasks.each do |task| %> <----------- this line
<%= render partial: 'task', object: task %>
<% end %>
</div>
<div class="buffer-top"><%= link_to "Back to Lists", lists_path, class: 'btn btn-primary btn-sm' %></div>
</div>
class Task < ApplicationRecord
belongs_to :lists
def complete!
self.completed = true
save
end
end
class List < ApplicationRecord
has_many :tasks
end
schema
ActiveRecord::Schema.define(version: 2020_04_06_202846) do
create_table "lists", force: :cascade do |t|
t.string "title"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
create_table "tasks", force: :cascade do |t|
t.string "title"
t.boolean "completed"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
end
You have belongs_to :lists in your Task model but no list_id in your corresponding tasks table. Your tasks table needs a migration with t.integer "list_id", :null => false in it.
create_table "tasks", force: :cascade do |t|
t.integer "list_id", :null => false
t.string "title"
t.boolean "completed"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end

No route matches [PATCH] "/users/1/articles" error on Ruby on Rails

I'm very very new to this, and I'm trying to implement a to-do-list which allows use of tags with user authentication. When updating the task, I get a routing error which states No route matches [PATCH] "/users/1/articles". I suspect it's because I didn't pass the article ID when updating the article. Could anyone please help guide me on how to solve this? Any advice will be greatly appreciated thank you!
Routes from the error page
user_article_path GET /users/:user_id/articles/:id(.:format)
articles#show
PATCH /users/:user_id/articles/:id(.:format)
articles#update
PUT /users/:user_id/articles/:id(.:format)
articles#update
DELETE /users/:user_id/articles/:id(.:format)
articles#destroy
Routes.rb
Rails.application.routes.draw do
get 'sessions/new'
get 'welcome/index'
get '/signup', to: 'users#new'
post '/signup', to: 'users#create'
get '/login', to: 'sessions#new'
post '/login', to: 'sessions#create'
delete '/logout', to: 'sessions#destroy'
resources :users do
resources :articles
end
get 'tags/:tag', to: 'articles#index', as: :tag, :constraints => { :tag => /[^\/]+/ }
root 'welcome#index'
end
article.rb
class Article < ApplicationRecord
attr_accessor :content, :name, :tag_list
before_create :downcase_fields
has_many :taggings , dependent: :destroy
has_many :tags, through: :taggings, dependent: :destroy
belongs_to :user
validates :user_id, presence: true
validates :title, presence: true,
length: { minimum: 1}
def self.tagged_with(name)
Tag.find_by_name!(name).articles
end
def downcase_fields
self.title.downcase
end
def self.tag_counts
Tag.select("tags.*, count(taggings.tag_id) as count").
joins(:taggings).group("taggings.tag_id")
end
def tag_list
tags.map(&:name).join(", ")
end
def tag_list=(names)
self.tags = names.split(",").map do |n|
Tag.where(name: n.strip).first_or_create!
end
end
def self.search(term)
if term
where('title LIKE ?', "%#{term}%").order('id DESC')
else
order('id DESC')
end
end
end
articles_controller
class ArticlesController < ApplicationController
before_action :correct_user
def index
#user = User.find(params[:user_id])
#articles = #user.articles.search(params[:term])
# if params[:tag]
# #articles = #user.articles.tagged_with(params[:tag])
# else
# #articles = #user.articles.all
# end
end
def show
#user = User.find(params[:user_id])
#article = #user.articles.find(params[:id])
end
def new
#user = User.find(params[:user_id])
#article = #user.articles.new
end
def edit
#user = User.find(params[:user_id])
#article = #user.articles.find(params[:id])
end
def create
#user = User.find(params[:user_id])
#article = #user.articles.new(article_params)
if #article.save
redirect_to user_articles_url
else
render 'new'
end
end
def update
#user = User.find(params[:user_id])
#article = #user.articles.find(params[:id])
if #article.update(article_params)
redirect_to user_articles_path
else
render 'edit'
end
end
def destroy
#user = User.find(params[:user_id])
#article = #user.articles.find(params[:id])
#article.destroy
redirect_to user_articles_path
end
private
def article_params
params.require(:article).permit(:title, :text, :tag_list, :term)
end
# Confirms a logged_in user_
def logged_in_user
unless logged_in?
store_location
flash[:danger] = "Please log in."
redirect_to login_url
end
end
# Confirms the correct user
def correct_user
#user = User.find(params[:user_id])
redirect_to(root_url) unless current_user?(#user)
end
end
db.schema.rb
ActiveRecord::Schema.define(version: 2019_01_27_093653) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "articles", force: :cascade do |t|
t.string "title"
t.text "text"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.bigint "user_id"
t.index ["user_id"], name: "index_articles_on_user_id"
end
create_table "taggings", force: :cascade do |t|
t.bigint "tag_id"
t.bigint "article_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.bigint "user_id"
t.index ["article_id"], name: "index_taggings_on_article_id"
t.index ["tag_id"], name: "index_taggings_on_tag_id"
t.index ["user_id"], name: "index_taggings_on_user_id"
end
create_table "tags", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "users", force: :cascade do |t|
t.string "name"
t.string "email"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "password_digest"
t.string "remember_digest"
t.index ["email"], name: "index_users_on_email", unique: true
end
add_foreign_key "articles", "users"
add_foreign_key "taggings", "articles"
add_foreign_key "taggings", "tags"
add_foreign_key "taggings", "users"
end
User controller
class UsersController < ApplicationController
before_action :logged_in_user, only: [:index, :edit, :update]
before_action :correct_user, only: [:edit, :update]
def show
#user = User.find(params[:id])
redirect_to user_articles_path(#user)
end
def new
#user = User.new
end
def index
#users = User.paginate(page: params[:page])
end
def create
#user = User.new(user_params)
if #user.save
log_in #user
flash[:success] = "Welcome to the To-Do-Manager!"
redirect_to user_articles_path(#user)
else
render 'new'
end
end
def edit
#user = User.find(params[:id])
end
def update
#user = User.find(params[:id])
if #user.update_attributes(user_params)
flash[:success] = "Profile updated"
redirect_to #user
else
render 'edit'
end
end
private
_form.html.erb(Create and update share the same form)
<%= form_with model: #article,url: user_articles_path(#user), local: true do |form| %>
<% if #article.errors.any? %>
<div id="error_explanation">
<h2>
<%= pluralize(#article.errors.count, "error") %> prohibited
this article from being saved:
</h2>
<ul>
<% #article.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<%= form.label :Task %><br>
<%= form.text_field :title %>
</p>
<p>
<%= form.label :Deadline %><br>
<%= form.text_area :text %>
</p>
<p>
<%= form.label :tag_list, "Tags (separated by commas)" %><br />
<%= form.text_field :tag_list %>
</p>
<p>
<%= form.submit %>
</p>
<% end %>
Your user article path should be singular according to your routes:
<%= form_with model: #article, url: user_article_path(#user), local: true do |form| %>
You routes requires two parameters: the user (:user_id) and the article (:id), you are only passing the user user_articles_path(#user) and also using the plural form, and that route does not exists with that HTTP method.
You have to use url: user_article_path(#user,#article) (or you can use the shortcut version url: [#user, #article]).

rails updating a user's record by their email

I have an app with an account model and an account manager (user).
I would like the account manager to be able to add other users to the account by typing in their email.
The account id of the account manager should be added to the new user's record.
My model looks like
class Account < ActiveRecord::Base
has_many users
...
end
class User < ActiveRecord::Base
belongs_to account
...
end
In the console it's fairly simple.
u = User.find(2)
u.update_attributes(account_id: 1)
But I'm not sure how to do this on the site.
I have the below partial which renders fine but when I put an email in the box nothing happens.
I get the message, user not added.
<h4>Add User</h4>
<div class = "row">
<div class="col-md-6 col-md-offset-3">
<%= form_for(:add_user, url: add_users_path) do |f| %>
<%= f.hidden_field #account = Account.find(params[:id]) %>
<%= f.label :email %>
<%= f.email_field :email, class:'form-control' %>
<%= f.submit "Submit", class: "btn btn-primary" %>
<% end %>
</div>
</div>
I don't necessarily want/need to route to another page for example "url: add_users_path" but without that line the code breaks and won't render.
I added this to user.rb
def add_user_to_account
update_attribute(:account_id)
end
I also created this controller
class AddUsersController < ApplicationController
before_action :get_user, only: [:edit, :update]
def new
end
def edit
end
def create
#user = User.find_by(email: params[:email])
if #user
#user.add_user_to_account
flash[:info] = "Added User to Account"
redirect_to accounts_url
else
flash[:danger] = "User NOT Added"
redirect_to accounts_url
end
end
def update
if params[:user][:account_id].empty?
#user.errors.add(:account_id, "can't be empty")
render 'edit'
elsif #user.update_attributes(user_params)
log_in #user
flash[:success] = "Account Updated"
redirect_to #user
else
render 'edit'
end
end
private
def user_params
params.require(:user).permit(:account_id, :user_id)
end
def get_user
#user = User.find_by(email: params[:email])
end
end
Am I on the right track? Is there a better way to do this?
UPDATE: Added schema
create_table "accounts", force: :cascade do |t|
t.string "name"
t.integer "account_manager_id"
t.integer "subscription_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "users", force: :cascade do |t|
t.string "name"
t.string "password_digest", null: false
t.string "remember_digest"
t.string "email", null: false
t.string "activation_digest"
t.boolean "activated"
t.datetime "activated_at"
t.string "reset_digest"
t.datetime "reset_sent_at"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.boolean "access_granted"
t.boolean "requested_access"
t.string "slug"
t.integer "account_id"
end
I think that you had the params wrong.
you are using params[:email] instead of params[:add_user][:email] to find the user by email
in you controller
class UsersController < ApplicationController
...
def add_users
user = User.find_by(email: params[:add_user][:email])
if user
user.add_user_to_account
...
else
...
end
end
end

how do I correctly make an active record query from one table to another?

Been stuck on this all afternoon/evening. Would really appreciate the help as I continue to work on this.
I have two different tables. Posts (status and photo) and Places (address). I'd like to combine these (status, photo, address) into one form and one show.
So, I think I am having trouble making an Active Record Query Interface. However, I may have messed up in Associating the tables...
Post.rb Model
class Post < ActiveRecord::Base
belongs_to :place
belongs_to :user
has_many :comments
has_many :commenters, through: :comments, source: :user
end
Place.rb Model
class Place < ActiveRecord::Base
has_many :posts
end
Posts _form.html.erb
<%= form_for(#post) do |f| %>
<% if #post.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#post.errors.count, "error") %> prohibited this post from being saved:</h2>
<ul>
<% #post.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :status %><br>
<%= f.text_field :status %>
</div>
<div class="field">
<%= f.label :upload %><br>
<%= f.text_field :upload %>
</div>
<%= f.label :place %><br>
<%= f.text_field :place %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Posts show.html.erb
<h1><%= #post.status %></h1>
<p><%= link_to #post.upload, #post.upload %></p>
<p><%= #post.place %></p>
<%= form_for [#post, #comment] do |f| %>
<p>
<%= f.text_area :response, placeholder: "Add a comment...", :rows => 8, :cols => 40 %>
</p>
<%= f.submit %>
<% end %>
<ul class="comments">
<% #post.comments.each do |comment| %>
<li><%= "#{comment.user.try(:email)} posted: #{comment.response}" %></li>
<% end %>
</ul>
<p><%= link_to "Back to home page", root_path %></p>
posts_controller.rb
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
# GET /posts
# GET /posts.json
def index
#posts = Post.all
end
# GET /posts/1
# GET /posts/1.json
def show
#post = Post.find params[:id]
#comment = Comment.new(:post => #post)
end
# GET /posts/new
def new
#post = Post.new
end
# GET /posts/1/edit
def edit
end
def create
safe_post = params.require(:post).permit(:status, :upload)
#post = current_user.posts.new safe_post
#post.place = Place.from_params params[:place]
#post.save
redirect_to #post
end
# PATCH/PUT /posts/1
# PATCH/PUT /posts/1.json
def update
respond_to do |format|
if #post.update(post_params)
format.html { redirect_to #post, notice: 'Post was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# DELETE /posts/1
# DELETE /posts/1.json
def destroy
#post.destroy
respond_to do |format|
format.html { redirect_to posts_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_post
#post = Post.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def post_params
params.require(:post).permit(:status, :upload)
end
end
places_controller.rb
class PlacesController < ApplicationController
before_action :set_place, only: [:show, :edit, :update, :destroy]
# GET /places
# GET /places.json
def index
#places = Place.all
end
# GET /places/1
# GET /places/1.json
def show
#place = Place.find params[:id]
end
# GET /places/new
def new
#place = Place.new
end
# GET /places/1/edit
def edit
end
# POST /places
# POST /places.json
def create
#place = Place.new(place_params)
respond_to do |format|
if #place.save
format.html { redirect_to #place, notice: 'Place was successfully created.' }
format.json { render action: 'show', status: :created, location: #place }
else
format.html { render action: 'new' }
format.json { render json: #place.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /places/1
# PATCH/PUT /places/1.json
def update
respond_to do |format|
if #place.update(place_params)
format.html { redirect_to #place, notice: 'Place was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #place.errors, status: :unprocessable_entity }
end
end
end
# DELETE /places/1
# DELETE /places/1.json
def destroy
#place.destroy
respond_to do |format|
format.html { redirect_to places_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_place
#place = Place.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def place_params
params.require(:place).permit(:address, :latitude, :longitude)
end
end
schema.rb
ActiveRecord::Schema.define(version: 20140324213459) do
create_table "comments", force: true do |t|
t.integer "user_id"
t.integer "post_id"
t.string "response"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "comments", ["post_id"], name: "index_comments_on_post_id"
add_index "comments", ["user_id"], name: "index_comments_on_user_id"
create_table "places", force: true do |t|
t.string "address"
t.float "latitude"
t.float "longitude"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "posts", force: true do |t|
t.string "status"
t.string "upload"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "user_id"
t.integer "place_id"
end
add_index "posts", ["place_id"], name: "index_posts_on_place_id"
add_index "posts", ["user_id"], name: "index_posts_on_user_id"
create_table "users", force: true do |t|
t.string "name"
t.string "photo"
t.string "bio"
t.datetime "created_at"
t.datetime "updated_at"
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
end
add_index "users", ["email"], name: "index_users_on_email", unique: true
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
routes.rb
DondeApp::Application.routes.draw do
resources :posts do
resources :comments, only: :create
resources :places
end
devise_for :users
root 'posts#index'
end
you need nested model form, look up this http://railscasts.com/episodes/196-nested-model-form-part-1
You seem to try to access #post.place in your _form.html.erb which might actually work through AREL magic, but you will probably get some strange results putting it into a text_field. Usually you would use a select box to select from existing places or whip up a jQuery control to find the right reference.
So the query in your show action should actually work to produce a suitable Post object, given it was set up correctly in the create action. You do have some code in there using Place.from_params to create a new place using a mysterious params[:place] that does not seem to be permitted (for the Post object that is). As your form only contains a text_field to refer to the place I have my doubts that this will work.
Check out your Post objects in the rails console and see wether the refer to a valid Place object. If they do you have to reflect this in your view, accessing the place attribute of your #post object will return a whole object which does not "know" how to present itself in a text_field, much less to create itself from one.
I guess this is the main problem you are having, but it is difficult to tell if you do not tell us what you expect and what you get instead.
Given this, you could optimize your AREL-queries to use includes(:place) in order to avoid the n+1 queries problem, but that would just apply to your index action. Otherwise I think AREL has you mostly covered.

Creating a form for a controller inside the show of another controller

I am currently using Rails 4 to create a website and I need to create a form for a model "candidature" inside a model "post" using another model "reponse".
This the post model :
class Post < ActiveRecord::Base
validates :title, presence: true,
length: { minimum: 5 }
belongs_to :entrepreneur
belongs_to :categorie
has_many :candidatures
accepts_nested_attributes_for :candidatures
has_many :questions
accepts_nested_attributes_for :questions,
:reject_if => lambda { |a| a[:enonce].blank? },
:allow_destroy => true
end
The candidature model :
class Candidature < ActiveRecord::Base
has_many :reponses
accepts_nested_attributes_for :reponses, :allow_destroy => true
end
And the reponse model :
class Reponse < ActiveRecord::Base
belongs_to :candidature
end
I don't have controllers for candidature and reponse, because i don't think i need any (do correct me if I'm wrong).
I have created posts that are projects and in the show view of posts, i need to create a form where a guest can answer some questions through answer and all those answers have to be saved in one candidature.
The schema.rb looks like that :
ActiveRecord::Schema.define(version: 20130718083016) do
create_table "candidatures", force: true do |t|
t.datetime "created_at"
t.datetime "updated_at"
t.integer "post_id"
end
create_table "questions", force: true do |t|
t.datetime "created_at"
t.datetime "updated_at"
t.integer "post_id"
t.text "enonce"
end
create_table "reponses", force: true do |t|
t.integer "candidature_id"
t.datetime "created_at"
t.datetime "updated_at"
t.text "enonce"
end
create_table "posts", force: true do |t|
t.string "title"
t.datetime "created_at"
t.datetime "updated_at"
t.text "defi"
t.text "mission"
t.text "competences"
t.text "gain"
t.text "lieny"
t.text "liendb"
t.string "link"
end
The controller for post :
class PostsController < ApplicationController
layout :resolve_layout
include Candidaturetopost
def new
#post = Post.new
end
def create
#post = Post.new(post_params)
if #post.save
flash[:notice] = "Successfully created project."
redirect_to #post
else
render 'new'
end
end
def show
#post = Post.find(params[:id])
#post.candidatures.build
end
def index
#posts = Post.all
end
def edit
#post = Post.find(params[:id])
end
def update
#post = Post.find(params[:id])
if #post.update(post_params)
redirect_to #post
else
render 'edit'
end
end
def destroy
#post = Post.find(params[:id])
#post.destroy
redirect_to posts_path
end
private
def post_params
params.require(:post).permit(:title, :image, :defi, :mission, :competences, :gain, :lieny, :liendb, :link, questions_attributes: [:enonce, :post_id, :id, :_destroy],
candidatures_attributes: [:post_id, :id, reponses_attributes: [:candidature_id, :id, :enonce]])
end
The show view i have tried to get working :
<%= form_for #post do |f| %>
<%= f.fields_for :candidatures do |cform| %>
<ol>
<% for question in #post.questions %>
<li><%= question.enonce %></li>
<%= cform.fields_for :reponses do |rform| %>
<%= rform.text_area :enonce %>
<% end %>
<% end %>
</ol>
<%= cform.submit %>
<% end %>
<% end %>
With the code shown here, the text_area for enonce isn't even displayed.
Is what I want to do even possible ? How can I have something similar if not ?
Try this
#post.candidatures.build
#post.candidatures.each {|candidature| candidature.responses.build }
But as I wrote in comment you overcomplicated the model structure and I belive you should rethink it.
You were right, it was way too complicated.
I used this to help me get it working, I have now the links I wanted between my three models.

Resources