Method create and destroy doesn't work : ruby on rails - ruby-on-rails

I am beginner on coding and on Ruby on rails.
I start to code an app to reference my favorite restaurants.
I start coding my action on my Restaurant Controller and the action Index, Show and Update work.
But I don't understand why my method create and destroy don't work.
Data base : schema.rb :
create_table "restaurants", force: :cascade do |t|
t.string "name"
t.string "price"
t.string "address"
t.string "category"
t.string "website"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.bigint "user_id"
t.index ["user_id"], name: "index_restaurants_on_user_id"
end
Model : restaurant.rb :
class Restaurant < ApplicationRecord
belongs_to :user
CATEGORY = ['Gourmand', 'Healthy', 'Asiatique', 'Italien', 'Cuisine du monde', 'Traditionel',
'Festive', 'Chic', 'Populaire', 'Fast-food', 'Casher', 'Halal', 'Vegan/Végétarien']
PRICE = ['€', '€€', '€€€', '€€€€']
validates :name, presence: true
validates :address, presence: true
validates :price, inclusion: { in: Restaurant::PRICE }, presence: true
validates :category, inclusion: { in: Restaurant::CATEGORY }, presence: true
end
Controller : restaurants_controller.rb
class RestaurantsController < ApplicationController
skip_before_action :authenticate_user!
before_action :set_restaurant, only: [:show, :edit, :update, :destroy]
def index
#restaurant = Restaurant.all
end
def show
end
def new
#restaurant = Restaurant.new
end
def create
#restaurant = Restaurant.new(restaurant_params)
#restaurant.save!
redirect_to restaurants_path(#restaurant), notice: 'new add'
# if #restaurant.save
# redirect_to restaurants_path(#restaurant), notice: 'New restaurant added'
# else
# render :new, status: :unprocessable_entity
# end
end
def edit
end
def update
#restaurant.update(restaurant_params)
redirect_to restaurant_path(#restaurant), notice: 'Restaurant was successfully updated.'
end
def destroy
#restaurant.destroy
redirect_to restaurants_path, status: :see_other
end
private
def restaurant_params
params.require(:restaurant).permit(
:name,
:address,
:category,
:website,
:price
)
end
def set_restaurant
#restaurant = Restaurant.find(params[:id])
end
end
View new : new.html.erb :
<h1>Add a new restaurant </h1>
<%= render 'restaurants/form', restaurant: #restaurant %>
View simple form : _form.html.erb
<%= simple_form_for(restaurant) do |f| %>
<%= f.input :name %>
<%= f.input :address %>
<%= f.input :category, collection: Restaurant::CATEGORY%>
<%= f.input :price, collection:Restaurant::PRICE %>
<%= f.input :website%>
<%= f.submit "#{ restaurant.persisted? ? 'Update' : 'Create' } Restaurant" %>
<%#= link_to 'Back to restaurant', restaurants_path %>
<% end %>
I add Devise Gems by the way but I skip the authentification with a :
skip_before_action :authenticate_user!
on my Restaurant Controller so it does not come from Devise.
Thank you :)
I check on my rails console : no restaurants created
When I put a 'raise' in the action 'create' just before my #restaurant.save, I can see on the params all the informations I added on my form.
But I don't know why it doesn't save my information and don't create the restaurant.

Related

Adding Comments Section To Posts In Rails

I am trying to add a comments section to posts on my web applications but getting an error when saving the comment
I have been following a tutorial to add a comments section to my posts and have been modifying as I go to work with my app. I am still relatively new to rails and I am still learning. I understand what the error message is telling me, but I am unsure as to how to proceed
Comments Controller:
class CommentsController < ApplicationController
def create
#micropost = Micropost.find_by(id: params[:id])
#comment =
#micropost.comments.create(params[:comment].permit(:body))
end
end
Microposts Contoller:
class MicropostsController < ApplicationController
before_action :logged_in_user, :upvote, :downvote, only:
[:create, :destroy]
before_action :correct_user, :upvote, :downvote, only:
:destroy, allow_destroy: true
def create
#micropost = current_user.microposts.build(micropost_params)
#maximum_length = Micropost.validators_on( :content,
:headline).first.options[:maximum]
if #micropost.save
flash[:success] = "Article Posted"
redirect_to root_url
else
#feed_items = []
render 'articles/home'
end
end
def destroy
#micropost.destroy
flash[:success] = "Micropost deleted"
redirect_to request.referrer || current_user
end
def show
#micropost = Micropost.find(params[:id])
end
private
def micropost_params
params.require(:micropost).permit(:content, :headline)
end
def correct_user
#micropost = current_user.microposts.find_by(id: params[:id])
redirect_to root_url if #micropost.nil?
end
end
Comments Form being rendered on post:
<%= form_for([#micropost, #micropost.comments.build]) do |f| %>
<br>
<p>
<%= current_user.name %>
<%= f.text_area :body %>
</p>
<br>
<p>
<%= f.submit %>
</p>
<% end %>
Comments Model:
class Comment < ApplicationRecord
belongs_to :micropost
end
Microposts Model:
class Micropost < ApplicationRecord
acts_as_votable
has_many :comments
belongs_to :user
validates :user_id, presence: true
validates :headline, presence: true, length: { maximum: 200 }
validates :content, presence: true, length: { maximum: 5000 }
end
Tables:
create_table "comments", force: :cascade do |t|
t.string "name"
t.text "body"
t.bigint "microposts_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "micropost_id"
t.index ["microposts_id"], name:
"index_comments_on_microposts_id"
end
create_table "microposts", force: :cascade do |t|
t.text "content"
t.bigint "user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.text "headline"
t.index ["user_id", "created_at"], name:
"index_microposts_on_user_id_and_created_at"
t.index ["user_id"], name: "index_microposts_on_user_id"
end
The form is being rendered on the micropost show view. I can see the form fine.
When I press to save the comment on the post I get an error stating undefined method comments for nil:NilClass and it highlights the Comments controller and the line #comment = #micropost.comments.create(params[:comment].permit(:body))
I know there probably should a method somewhere for comments. The tutorial I watched didn't add anything like that. So I unsure do I need to modify some existing code, or do I need to add a method somewhere called comments?
where is the form to create comments, you are not sending the parameter params [: id], and with this parameter you are looking for the # micropost .. you must send the id in that form, a quick solution could be
<% = f.hidden_field: id, value: # micropost.id%>
 
in the comment creation form
Okay so the answers you all gave pointed me in the right direction. I wasn't actually passing an proper id. Instead of #micropost = Micropost.find_by(id: params[:id]) it should have been #micropost = Micropost.find_by(id: params[:micropost_id])
Many thanks all for getting me there.

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]).

How to set up nested resources controller in Rails 4?

I have 3 models in my application. User (via Devise), post, and reply.
User can be parent of both posts and replies, and reply belongs to users and posts.
For some reason it doesn't save replies to database. On output i can not see user_id. The function i used to create #reply is current_user.replies.create(reply_params). Also html outputs braces seem bit odd to me. Why is only :comment in :replys braces? Any idea what i did wrong?
Models:
class Post < ActiveRecord::Base
belongs_to :user
has_many :replies
validates_presence_of :title, :tekst
validates :tekst, length: {minimum: 10}
end
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :posts, dependent: :destroy
has_many :replies
end
class Reply < ActiveRecord::Base
belongs_to :post
belongs_to :user
validates_presence_of :user, :post, :comment
validates :comment, length: {minimum: 10}
end
Controller:
class RepliesController < ApplicationController
before_action :set_post, only: [:new, :index, :create]
before_filter :authenticate_user!
def index
#replies = #post.replies
end
def new
#reply = Reply.new
end
def create
#reply = current_user.replies.create(reply_params)
respond_to do |format|
if #reply.save
format.html { redirect_to #post, notice: 'Reply was
successfully saved' }
format.json { render json: #post }
else
format.html { render :new }
format.json { render json: #post.errors, status: 'Wrong entry'
}
end
end
end
private
def reply_params
params.require(:reply).permit(:comment, :post_id)
end
def set_post
#post = Post.find(params[:post_id])
end
end
Form:
<%= form_for [#post, #reply] do |f| %>
<%= f.text_field :comment %>
<% f.hidden_field :post_id, value: #post.id %>
<%= f.submit %>
<% end %>
Schema:
create_table "replies", force: :cascade do |t|
t.integer "post_id"
t.integer "user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.text "comment"
end
add_index "replies", ["post_id"], name: "index_replies_on_post_id"
add_index "replies", ["user_id"], name: "index_replies_on_user_id"
And how it looks at output:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"lot of nubers",
"reply"=>{"comment"=>"sdfsddasd"}, "commit"=>"Create Reply",
"post_id"=>"1"}
It's failing because you are not associating a post with the reply. Try this...
def create
#reply = #post.replies.new(reply_params)
#reply.user = current_user
respond_to do |format|
if #reply.save
...
end
end
Also, notice that you should instantiate the reply (with new, instead of create), then save it.

How do I save my child records from the parent controller?

I have a bunch of 'kid' objects saved already and I want to create a parent object which is linked to the kids via a 'relative' model.
This object gives me a many-to-many, through relatives.
To be clear: the user visits the 'parents' page, clicks create parents and is presented with a form that lets them name the parent and add up to four children to this parent (by creating 'relatives'), each of these 'relations' is also named - that's an important part. So, I could name the relation 'step son' or 'son', for instance.
Here's the code I have so far:
class Kid < ActiveRecord::Base
has_many :relatives
has_many :parents, through: :relatives
end
class Parent < ActiveRecord::Base
has_many :relatives
has_many :kids, through: :relatives
accepts_nested_attributes_for :relatives,
:reject_if => lambda { |a| a[:content].blank? },
:allow_destroy => true
end
class Relative < ActiveRecord::Base
belongs_to :parent
belongs_to :kid
end
class ParentsController < ApplicationController
before_action :set_parent, only: [:show, :edit, :update, :destroy]
before_action :lookup_kids, only: [:new, :edit]
# GET /parents
# GET /parents.json
def index
#parents = Parent.all
end
# GET /parents/1
# GET /parents/1.json
def show
end
# GET /parents/new
def new
#parent = Parent.new
4.times { #parent.relatives.build }
end
# GET /parents/1/edit
def edit
end
# POST /parents
# POST /parents.json
def create
#parent = Parent.new(parent_params)
parent_params[:relatives_attributes].each do |k,r|
#parent.relatives.build(r.except(:_destroy))
end
respond_to do |format|
if #parent.save
format.html { redirect_to #parent, notice: 'Parent was successfully created.' }
format.json { render :show, status: :created, location: #parent }
else
format.html { render :new }
format.json { render json: #parent.errors, status: :unprocessable_entity }
end
end
end
# cut for brevity.
private
# Use callbacks to share common setup or constraints between actions.
def set_parent
#parent = Parent.find(params[:id])
end
def parent_params
params.require(:parent).permit(:name,
relatives_attributes: [:parent_id, :kid_id, :relationship, :_destroy])
end
def lookup_kids
#kids = Kid.all #for this nursery.
end
end
<%= form_for(#parent) do |f| %>
<% if #parent.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#parent.errors.count, "error") %> prohibited this parent from being saved:</h2>
<ul>
<% #parent.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<h4>Kids:</h4>
<%= f.fields_for :relatives do |r| %>
<%= r.label :kid %>
<%= r.collection_select :kid_id,
#kids, :id, :name, include_blank: true%>
<%= r.label :relationship %>
<%= r.text_field :relationship %>
<%= r.check_box :_destroy %>
<%= r.label :_destroy, "Remove" %>
<br/>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
ActiveRecord::Schema.define(version: 20151030113634) do
create_table "kids", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "parents", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "relatives", force: :cascade do |t|
t.string "relationship"
t.integer "parent_id"
t.integer "kid_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "relatives", ["kid_id"], name: "index_relatives_on_kid_id"
add_index "relatives", ["parent_id"], name: "index_relatives_on_parent_id"
end
When I get to 'create' in the parents controller, I can see the right parameters are getting through but the relationship records aren't being saved. SHouldn't this happen automatically?
I've tried looping through the :relatives_attributes but that doesn't seem to work with 'build'.
How am I suppsed to get the 'relatives' records to save?
EDIT: adding parameters posted:
parent"=>{
"name"=>"Dad",
"relatives_attributes"=>{
"0"=>{"kid_id"=>"2", "relationship"=>"Son", "_destroy"=>"0"},
"1"=>{"kid_id"=>"", "relationship"=>"", "_destroy"=>"0"},
"2"=>{"kid_id"=>"", "relationship"=>"", "_destroy"=>"0"},
"3"=>{"kid_id"=>"", "relationship"=>"", "_destroy"=>"0"}}}
Edit: I've updated this to show my latest edit - note the 'parent_params[:relatives_attributes].each do |k,r|' in the controller. This now saves the kid records but the only problem is, it also saves the fields that are blank! So I have 'relative' records with null values for kid records. How can I stop it saving empty fields (or creating empty relative records)?
The answer was to build each sub-record of relative, like so:
parent_params[:relatives_attributes].each do |k,r|
#parent.relatives.build(r.except(:_destroy))
end
Before calling #parent.save.
However, I'm still having issues getting rid of the blank records. So if anyone has an answer to that problem, please comment here - or if there's a better or more traditional way of doing this, hit me up. Follow up question here: Why is this reject_if in my model not rejecting blank records?
You are almost there, depending upon how your form submission is, you most likely need an accepts_nested_attribute_for in your Relative associative class as well:
class Relative
belongs_to :parent
accepts_nested_attributes_for :parent
belongs_to :kid
accepts_nested_attributes_for :kid
end
If this doesn't work, then please submit your params that are passed into the controller and we can adjust accordingly

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.

Resources