so i have installed best in place gem in a rails 4 environment and initialised it correctly. (i can click on the name field and the box becomes editable).
I've this code in my admin_namespaced user controller
class Admin::UsersController < Admin::BaseController
def index
#users = User.all
# #columns = User.column_names
end
def show
#user = User.find(params[:id])
end
def update
#user = User.find params[:id]
respond_to do |format|
if #user.update_attributes(user_params)
format.html { redirect_to(user, :notice => 'User was successfully updated.') }
format.json { respond_with_bip(#user) }
else
format.html { render :action => "index" }
format.json { respond_with_bip(#user) }
end
end
end
private
def user_params
params.require(:user).permit(:name,:email,:password,:password_confirmation)
end
end
and basically i want to use it in conjuction with rails datatables gem that i successfully setup, to inline-edit corresponding fields.
this is the html.erb code in my user index view
<% provide(:title, 'All users') %>
<h1>All users</h1>
<%= link_to "Back", admin_path %>
<table class="display responsive no-wrap text-center" id="usertableadmin">
<thead>
<tr>
<th>id</th>
<th>Username</th>
<th>Email</th>
<th>Activated?</th>
<th>Admin?</th>
</tr>
</thead>
<tbody>
<% #users.each do |user| %>
<tr>
<td><%= user.id %></td>
<td><%= best_in_place user, :name%></td>
<td><%= user.email %></td>
<td><%= user.activated %></td>
<td><%= user.admin %></td>
</tr>
<% end %>
</tbody>
</table>
here is what the html code looks like on the tag that has the best_in_place initialization.
<span data-bip-type="input" data-bip-attribute="name" data-bip-object="user" data-bip-original-content="Example User" data-bip-url="/users/1" data-bip-value="Example User" class="best_in_place" id="best_in_place_user_1_name">Example User</span>
I dont know for sure but for some reason the fields do not get updated. When i click to change the name it gets reverted to the previous one.
I dont know if its because i have a namespace, admin/users or its because its the index action and not the show action.
any insight is welcome.
I've found the solution,
it seems the error was the update url it was wrong because of the namespace.
What i had to do, was to include url parameter like below
<td><%= best_in_place user, :name, url: "users/#{user.id}" %></td>
Related
I searched for the answer, but I couldn't find the same problem.
Basically - I'm building a simple CMS, and I'm building a controller with a view, but it isn't working. I can press the submit button, but the form gives no response, it doesn't even output any errors.
I also noticed it changes the url from /pages/new to /pages, but it stays on the form.
Page Controller:
def index
#pages = Page.sorted
end
def show
#page = Page.find(params[:id])
end
def new
#page = Page.new
end
def create
#page = Page.new(page_params)
if #page.save
flash[:notice] = "Page created succesfully."
redirect_to pages_path
else
render('new')
end
end
def edit
#page = Page.find(params[:id])
end
def update
#page = Page.find(params[:id])
if #page.update_attributes(page_params)
flash[:notice] = "Subject updated succesfully."
redirect_to page_path(#page)
render('edit')
end
end
def delete
#page = Page.find(params[:id])
end
def destroy
#page = Page.find(params[:id])
#page.destroy
flash[:notice] = "Page '#{#page.name}' destoyed succesfully."
redirect_to(pages_path)
end
private
def page_params
params.require(:page).permit(:subject_id, :name, :position, :visible, :permalink)
end
new.html.erb:
<%= link_to("<< Back To List", pages_path, :class => 'back-link') %>
<div class = "pages new">
<h2>Create Page</h2>
<%= form_for(#page, :url => pages_path, :method => 'post') do |f| %>
<table summary = "Page form fields">
<tr>
<th> Name: </th>
<td><%= f.text_field(:name) %></td>
</tr>
<tr>
<th> Subject ID: </th>
<td><%= f.text_field(:subject_id) %></td>
</tr>
<tr>
<th> Permalink: </th>
<td><%= f.text_field(:permalink) %></td>
</tr>
<tr>
<th>Position: </th>
<td><%= f.text_field(:position) %></td>
</tr>
<tr>
<th>Visible: </th>
<td><%= f.text_field(:visible) %></td>
</tr>
</table>
<div class="form-buttons">
<%= f.submit("Create Page") %>
</div>
<% end %>
</div>
EDIT:
tried changing the form code to <%= form_for(#page) do |f| %>, but I still have the same problem
I added the #page.save! part of the code and it gave me a error which showed me errors which are deeper down in my code! At least I fixed this problem. Thank you very much.
It seems that the information from your form is not valid, try using save! instead of save in your create action:
def create
#page = Page.new(page_params)
if #page.save!
flash[:notice] = "Page created succesfully."
redirect_to pages_path
else
render('new')
end
end
That will show the error on your logs.
I'm building a marketplace app where I'm trying to use the Best in Place gem to allow sellers to add a tracking number for each of their orders.
I get a NoMethodError which I'm not able to resolve.
NoMethodError in Orders#sales
undefined method `tracking' for nil:NilClass
The error points to the best in place line below in the view page. This view page is based on the method Sales (in the controller below) where I filter for orders for that particular seller.
Here is my routes.rb with order routing. Since orders need not be edited or destroyed, I didn't create an edit or delete route.
resources :listings do
resources :orders, only: [:new, :create, :update]
collection { post :import }
end
Here is a snippet from my orders controller
class OrdersController < ApplicationController
before_action :set_order, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!
before_action :check_user, only: [:edit, :update]
def sales
#orders = Order.all.where(seller: current_user).order("created_at DESC")
end
def update
#order.update_attributes(params[:order])
end
def check_user
if current_user.id != #seller && current_user.name != "admin admin"
redirect_to root_url, alert: "Sorry, you are not the seller of this listing"
end
end
Here is my view page:
<table class="table table-striped table-bordered">
<tr>
<th class="col-md-2">Image</th>
<th class="col-md-2">Item</th>
<th class="col-md-1">Price</th>
<th class="col-md-2">Customer</th>
<th class="col-md-2">Date Sold</th>
<th class="col-md-2">Shipment Tracking #</th>
<th class="col-md-1">Carrier (UPS, USPS, etc.)</th>
</tr>
<% #orders.each do |order| %>
<tr>
<td><%= image_tag order.listing.image.url(:thumb) %></td>
<td><%= order.listing.name %></td>
<td><%= number_to_currency(order.listing.price) %></td>
<td><%= order.buyer.name %></td>
<td><%= order.created_at.strftime("%B %-d, %Y") %></td>
<td><%= best_in_place #order, :tracking, :type => :input %> </td>
<td><%= best_in_place #order, :carrier, :type => :input %></td>
</tr>
<% end %>
</table>
Been stuck on this for a while. Appreciate any help on this.
I think the problem is that you are calling #order inside your .each method.
Try:
<%= best in place order, :tracking, :type => :input %>
You will need to change the next line in your view as well.
I figured it out. The problem was that since I was using best_in_place in a non-Activerecord environment (as part of a table with a list of orders), I needed to pass the order id explicitly. I found this in the best_in_place documentation https://github.com/bernat/best_in_place#non-active-record-environments
I created a custom route for the update action
put 'orderupdate' => "orders#update"
Then in my do loop in the view, I used the custom path for the route above and passed the order id to that route.
<% #orders.each do |order| %>
<tr>
<td><%= order.id %></td>
<td><%= image_tag order.listing.image.url(:thumb) %></td>
<td><%= order.listing.name %></td>
<td><%= number_to_currency(order.listing.price) %></td>
<td><%= order.buyer.name %></td>
<td><%= order.created_at.strftime("%B %-d, %Y") %></td>
<td><%= best_in_place order, :tracking, :type => :input, :url => orderupdate_path(id: order.id) %> </td>
<td><%= best_in_place order, :carrier, :type => :input, :url => orderupdate_path(id: order.id) %> </td>
</tr>
<% end %>
Here is the update method in my controller:
def update
#order = Order.find(params[:id])
respond_to do |format|
if #order.update(order_params)
format.html { redirect_to sales_url, notice: 'Order updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #order.errors, status: :unprocessable_entity }
end
end
end
Hope this helps someone!
What I Want:
I need in a view a button or a link (it doesn't matter) to the create action of Reservation controller and to give it a parameter too.
And resolve the ForbiddenAttributesError that now gives me.
Here are my model and controller:
Reservation model
class Reservation < ActiveRecord::Base
belongs_to :user
belongs_to :dinner
end
Reservation controller
class ReservationsController < ApplicationController
load_and_authorize_resource
def show
#reservations = Reservation.joins(:user).where('dinner_id' => params[:dinner_id]).select("users.*,reservations.*")
#dinnerid = params[:dinner_id]
respond_to do |format|
format.html
format.json { render :json => #reservations }
end
end
def create
#reservation = Reservation.new(params[:reservation])
#reservation.user_id = current_user.id
respond_to do |format|
if #reservation.save
format.html { redirect_to #reservation, notice: 'Reservation was successfully created.' }
format.json { render :show, status: :created, location: #reservation }
else
format.html { render :show }
format.json { render json: #reservation.errors, status: :unprocessable_entity }
end
end
end
# Never trust parameters from the scary internet, only allow the white list through.
def reservation_params
params.require(:reservation).permit(:dinner_id)
end
end
EDIT: After the suggestion of #Rahul Singh this is my actual code with relative error:
<p id="notice"><%= notice %></p>
<table>
<thead>
<tr>
<th>Id</th>
<th>User id</th>
<th>Dinner id</th>
<th>User email</th>
<th>User name</th>
</tr>
</thead>
<tbody>
<% #reservations.each do |reservation| %>
<tr>
<td><%= reservation.id %></td>
<td><%= reservation.user_id %></td>
<td><%= reservation.dinner_id %></td>
<td><%= reservation.user.email %></td>
<td><%= reservation.user.name %></td>
</tr>
<% end %>
</tbody>
</table>
<br/>TRY 00a <br/>
<%= form_for(Reservation.new) do |f| %>
<%= f.hidden_field( :dinner_id, :value => #dinnerid.to_s) %>
<%= f.submit "Join1" %>
<% end %>
<br/> !!!!!!!!!!ERROR : ActiveModel::ForbiddenAttributesError
<br/>TRY 00b <br/>
<%= link_to "Join1", reservations_path(dinner_id:#dinnerid.to_s), method: :post %>
<br/> !!!!!!!!!!ERROR : param is missing or the value is empty: reservation
I provide a sreenshot for the error :
Error of the form : https://www.dropbox.com/s/i2x1m520ptqdj56/createReservationForm.jpg
Error of the link_to : https://www.dropbox.com/s/8xjwee5oo7q6uhk/createReservationLink_to.jpg
This should work
<%= form_for(Reservation.new) do |f| %>
<%= f.hidden_field( :dinner_id, :value => #dinnerid.to_s) %>
<%= f.submit "Join1" %>
<% end %>
clicking on Join1 button will submit form to ReservationsController create action.
and with link try this
<%= link_to "Join1", reservations_path(dinner_id:#dinnerid.to_s), method: :post %>
for above to work,add following in your routes.rb
resources :reservations
Change this line -> #reservation = Reservation.new(params[:reservation])
To this -> #reservation = Reservation.new reservation_params
and try again ;).
I'm wondering if it wouldn't be better to have your reservation routes as a nested resource of dinners.
It seems reservations can't exist without a dinner, so I'd make that explicit like this:
# config/routes.rb
resources :dinners do
resources :reservations
end
Run rake routes to see how this would change the routes.
You'd now have the dinner id passed along:
# app/views/dinners/show.html.erb
<%= button_to 'Reserve this dinner', dinner_reservations_path(#dinner) %>
The button would route to the create action because a button's default HTTP method is POST.
# app/controllers/reservations_controller.rb
class ReservationsController < ApplicationController
before_action :set_dinner
def create
#dinner.reservations.create! user: current_user
# would render reservations/create.html.erb
end
private
def set_dinner
#dinner = Dinner.find(params[:id])
end
end
This doesn't fix your immediate problem of just getting that link to work. But I think you'd be a lot better served structuring your app more like the above going forward.
Full disclosure: the person who asked this question contacted me on twitter personally, so I took some liberties in answering this question with a more general design suggestion.
I'm not sure this is the "best" approach but I think its the easiest one.
You could do something with string interpolation:
a href="/reservations?dinner=#{dinner.id}" Join
then you could get the paramter with
params[:dinner]
I have a contacts model, with an attribute :area. I'd like to display one page (/listarea) as a list of all the areas. I have this part working
In contacts_controller.rb
def listarea
#listarea = Contact.order(:area).uniq.pluck(:area)
respond_to do |format|
format.html # index.html.erb
format.json { render json: #contacts }
end
end
And the listarea.html.erb
<table class="table table-striped table-hover">
<% #listarea.each do |area| %>
<tr class="tablerow">
<td><%= link_to area, :action => :areacontact, :area => area %></td>
</tr>
<% end %>
</table>
I'd like to be able to click on the area and lead to another page (areacontact) which will show a full list of all the contacts in that :area. This part is not working.
In contacts_controller.rb I have
def areacontacts
#contacts = Contact.order(:name).find_all_by_area(params[:area])
respond_to do |format|
format.html # index.html.erb
format.json { render json: #contacts }
end
end
And in areacontact.html.erb I have
<% #contacts.each do |contact| %>
Hello
<% end %>
The error when I view /areacontact is
ActionView::Template::Error (undefined method `each' for nil:NilClass):
Can anyone help?
Don't use <%= link_to area, :action => :areacontact, :area => area %> instead of use the path like areacontact_path check the proper path using rake routes. and
In the line #contacts = Contact.order(:name).find_all_by_area(params[:area]) seems like no attributes are passing properly pleas check what are the params you are getting in the action.
In your contacts_controller.rb, you need some tweaks when u have nothing to show in the view. I mean when your database contacts tables is empty.
So you can do like this in contacts_controller.rb
def areacontacts
#contacts = Contact.order(:name).find_all_by_area(params[:area]) rescue []
.....
...
end
You got error because of #contacts is not any result from your find_all_by_area query.
Also you can check nil in areacontact.html.erb before lopping #contacts like this:
<% if #contacts.present %>
<% #contacts.each do |contact| %>
Hello
<% end %>
<% end %>
I am very new to Rails and Web-programming and hope you can help me out with my very first project.
I am developing a website for a Real Estate Agency.
I have 3 tables in my database (Homes: Home_ID, Home_Name, Admin_ID; Admins: Admin_ID, Admin_Name, Admin_Email; Images: Image_ID, Image_Path, Image_Name, Home_ID, Admin_ID).
All 3 tables have been created using scaffold. The image information (name, path, image_id, home_id etc) have been entered in SQLite.
I get all text information of the different houses displayed correctly on the website except the pictures.
My attempt to link it in the view/home/index.html.erb created the following error:
undefined method `image_path' for #<Home:0xb63d85e0>
I used below code:
<% #homes.each do |home| %>
<tr>
<td><%= home.name %></td>
<td><%= home.details %></td>
<td><%= home.region %></td>
<td><%= home.address %></td>
<td><%= home.price %></td>
<td><%= home.admin_id %></td>
<td><%= home.image_path %></td>
</tr>
<% end %>
</table>
It looks like that the data entered in SQLite do not sync with rails.
Do you have any idea what I have done wrong and how I can fix it?
Thank you.
I'm not positive what the relationship would be between your images and home models would be so correct me if I'm wrong, but I'm guessing that homes will have many images. Each image would belong to one home. Is this correct? If so, you will need to declare that in your models like so:
models/home.rb
has_many :images
models/image.rb
belongs_to :home
You will then need to add this to the image database:
t.integer "home_id"
You can add it by going to the command line and typing:
rails g migration AddHomeToImages home_id:integer
You should look in db/migrate/ and then the most recent migration file and make sure it looks like this:
add_column :images, :home_id, :integer
Then run:
rake db:migrate
At this point you'll only need to update your controller and views to show this association. Let me know if this helps and if so I'll help you with your controller and views.
What's happening is that you are looping through a selection of records from the Home table. Because of this, when you call
<td><%= home.image_path %></td>
it's not recognizing the attribute image_path because you don't have image_path as a column of Home table. You only have Home_ID, Home_Name, Admin_ID for your columns. You will have to look into associations between models in order to figure out how to grab the image_path for each home record. You can start here.
If you update the code later on I'll be glad to comment on it.
I think that the best solution here will be to use paperclip gem.
You can take a look at this very old railscast eoisode just to understand how it works:
http://railscasts.com/episodes/134-paperclip
And here is github repository:
https://github.com/thoughtbot/paperclip
Paperclip will help you with paths, styles and preview for your images.
Thanks Jason,
I agree that it is a bit big for newbies, but the requirements were that we do a website where we need to read and write from/to a database. We had a quick introduction to rails with partnerwork and are now on our own and a "bit" lost and running out of time.
Here is the error message I am getting:
NameError in Homes#index
undefined local variable or method `image' for
<#:0xb62f7aa4>
Extracted source (around line #20):
17: <% #homes.each do |home| %>
18: <tr>
19: <td><%= home.name %></td>
20: <td><%= image.home_id %></td>
21: <td><%= home.details %></td>
22: <td><%= home.region %></td>
23: <td><%= home.address %></td>
When I create the database tables I had an Image_ID in the homes table, but I was told that I don`t need it and that it is enough to have only Home_ID in the images table.
I understand that the error is caused because of image.home_id.
What is your opinion? Should I add the Image_ID back to the homes table in order to display all images for the respective home_id or is there another way? I would like to be able to decide which picture will be displayed as the main picture and which ones as the smaller pictures.
Here is the code I use:
models/home.rb
class Home < ActiveRecord::Base
attr_accessible :address, :admin_id, :details, :name, :price, :region
has_many :images
end
models/image.rb
class Image < ActiveRecord::Base
attr_accessible :image_description, :image_name, :image_path
belongs_to :home
end
views/homes/index.html.erb
<h1>Listing homes</h1>
<table>
<tr>
<th>Name</th>
<th>Image</th>
<th>Details</th>
<th>Region</th>
<th>Address</th>
<th>Price</th>
<th>Admin</th>
<th></th>
<th></th>
<th></th>
</tr>
<% #homes.each do |home| %>
<tr>
<td><%= home.name %></td>
<td><%= image.home_id %></td>
<td><%= home.details %></td>
<td><%= home.region %></td>
<td><%= home.address %></td>
<td><%= home.price %></td>
<td><%= home.admin_id %></td>
<td><%= link_to 'Show', home %></td>
<td><%= link_to 'Edit', edit_home_path(home) %></td>
<td><%= link_to 'Destroy', home, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</table>
<br />
<%= link_to 'New Home', new_home_path %>
views/homes/show.html.erb
<p id="notice"><%= notice %></p>
<p>
<b>Name:</b>
<%= #home.name %>
</p>
<p>
<b>Image:</b>
<%= #image.home_id %>
</p>
<p>
<b>Details:</b>
<%= #home.details %>
</p>
<p>
<b>Region:</b>
<%= #home.region %>
</p>
<p>
<b>Address:</b>
<%= #home.address %>
</p>
<p>
<b>Price:</b>
<%= #home.price %>
</p>
<p>
<b>Admin:</b>
<%= #home.admin_id %>
</p>
<%= link_to 'Edit', edit_home_path(#home) %> |
<%= link_to 'Back', homes_path %>
views/images/_form.html.erb
<%= form_for(#image) do |f| %>
<% if #image.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#image.errors.count, "error") %> prohibited this image from being saved:</h2>
<ul>
<% #image.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :image_name %><br />
<%= f.text_field :image_name %>
</div>
<div class="field">
<%= f.label :image_path %><br />
<%= f.text_field :image_path %>
</div>
<div class="field">
<%= f.label :image_description %><br />
<%= f.text_area :image_description %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
controllers/images_controller.rb
class ImagesController < ApplicationController
# GET /images
# GET /images.json
def index
#images = Image.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #images }
end
end
# GET /images/1
# GET /images/1.json
def show
#image = Image.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #image }
end
end
# GET /images/new
# GET /images/new.json
def new
#image = Image.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #image }
end
end
# GET /images/1/edit
def edit
#image = Image.find(params[:id])
end
# POST /images
# POST /images.json
def create
#image = Image.new(params[:image])
respond_to do |format|
if #image.save
format.html { redirect_to #image, notice: 'Image was successfully created.' }
format.json { render json: #image, status: :created, location: #image }
else
format.html { render action: "new" }
format.json { render json: #image.errors, status: :unprocessable_entity }
end
end
end
# PUT /images/1
# PUT /images/1.json
def update
#image = Image.find(params[:id])
respond_to do |format|
if #image.update_attributes(params[:image])
format.html { redirect_to #image, notice: 'Image was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #image.errors, status: :unprocessable_entity }
end
end
end
# DELETE /images/1
# DELETE /images/1.json
def destroy
#image = Image.find(params[:id])
#image.destroy
respond_to do |format|
format.html { redirect_to images_url }
format.json { head :no_content }
end
end
end
Thank you so much. I really appreciate your help!!!