I am learning to use CRUD, and setup a page to add a record, however it only generated blank record? Can you take a look my code?
thanks!
here is the Page controller:
class PagesController < ApplicationController
def index
#test = Page.all
end
def new
#test = Page.new
end
def create
#test = Page.new(params.permit(:subject_id,:name,:position,:visible,:permalink))
if #test.save
flash[:notice] = "Page created successfully!"
redirect_to(:action => 'index')
else
render('new')
end
end
end
here is the new.html.erb
<%= link_to("<< Back to List", {:action => 'index'}, :class => 'back-link') %>
<div class="pages new">
<h2>Create Subject</h2>
<%= form_for(:Page, :url => {:action => 'create'}) do |f| %>
<table summary="Page form fields">
<tr>
<th>Subject_ID</th>
<td><%= f.text_field(:subject_id) %></td>
</tr>
<tr>
<th>Name</th>
<td><%= f.text_field(:name) %></td>
</tr>
<tr>
<th>Position</th>
<td><%= f.text_field(:position) %></td>
</tr>
<tr>
<th>Visible</th>
<td><%= f.text_field(:visible) %></td>
</tr>
<tr>
<th>Permalink</th>
<td><%= f.text_field(:permalink) %></td>
</tr>
</table>
<div class="form-buttons">
<%= submit_tag("Create Subject") %>
</div>
<% end %>
</div>
Here is index.html.erb
<div class="pages index">
<h2>Pages</h2>
# <%= link_to("Add New Page", {:action => 'new'}, :class => 'action new') %>
<table class="listing" summary="Page list">
<tr class="header">
<th>Position</th>
<th>Page Name</th>
<th>Visible</th>
<th>Pages</th>
<th>Actions</th>
</tr>
<% #test.each do |f| %>
<tr>
<td><%= f.position %></td>
<td><%= f.name %></td>
<td class="center"><%= f.visible %></td>
<td class="center"><%= f.permalink %></td>
<td class="actions">
<%= link_to("Show", {:action => 'show', :id => f.id}, :class => 'action show') %>
<%= link_to("Edit", {:action => 'edit', :id => f.id}, :class => 'action edit') %>
<%= link_to("Delete", {:action => 'delete', :id => f.id}, :class => 'action delete') %>
</td>
</tr>
<% end %>
</table>
</div>
Thanks so much!
Strong parameters
Rails sends form parameters in nested hashes.
{ page: { subject_id: 1, name: 'Hello World.' } }
So to whitelist the parameters you would do.
class PagesController < ApplicationController
def index
#test = Page.all
end
def new
#test = Page.new
end
def create
#test = Page.new(page_params)
if #test.save
flash[:notice] = "Page created successfully!"
redirect_to(:action => 'index')
else
render('new')
end
end
private
def page_parameters
params.require(:page)
.permit(:subject_id,:name,:position,:visible,:permalink)
end
end
which is like doing:
params[:page].slice(:subject_id,:name,:position,:visible,:permalink)
form_for and models
Also your form should read:
<%= form_for(:page, :url => {:action => 'create'}) do |f| %>
Or:
<%= form_for(#page, :url => {:action => 'create'}) do |f| %>
:Page will give you the wrong key in your parameters and prevent rails from binding the form to your #page object. (The values posted will disappear from the form when it's invalid).
Related
This is the error I get.
This is my model code.
class Subject < ActiveRecord::Base
has_many :pages
validates :name,
:presence => true,
:length => { :maximum => 255 }
scope :visible, lambda { where(:visible => true) }
scope :invisible, lambda { where(:visible => false) }
scope :sorted, lambda { order("subjects.position ASC")}
scope :newest_first, lambda { order("subject.created_at DESC") }
scope :search, lambda { |query|
where(["name LIKE ?", "%#{query}%"])
}
end
I noticed that it's saying something about my create action. So here's that:
class SubjectsController < ApplicationController
layout "admin"
def index
#subjects = Subject.sorted
end
def show
#subject = Subject.find(params[:id])
end
def new
#subject = Subject.new({:name => 'Default'})
#subject_count = Subject.count + 1
end
def create
# Instantiate a new object using form parameters
#subject = Subject.new(subject_params)
# Save the object
if #subject.save
# If save succeeds, redirect to the index
flash[:notice] = "The subject was created successfully."
redirect_to(:action => 'index')
else
#subject_count = Subject.count + 1
render(new)
end
end
def edit
#subject = Subject.find(params[:id])
#subject_count = Subject.count
end
def update
# Find an existing object using form parameters
#subject = Subject.find(params[:id])
# Update the object
if #subject.update_attributes(subject_params)
# If save succeeds, redirect to the show
flash[:notice] = "The subject was updated successfully."
redirect_to(:action => 'show', :id => #subject.id)
else
# If update fails, redisplay the form so user can fix problem.
#subject_count = Subject.count
render('edit')
end
end
def delete
#subject = Subject.find(params[:id])
end
def destroy
subject = Subject.find(params[:id]).destroy
flash[:notice] = "The subject '#{subject.name}' was deleted successfully."
redirect_to(:action => 'index')
end
private
def subject_params
# same as using "params[:subject]", except that it:
# -raises an error if :subject is not present
# -allows listed attributes to be mass-assigned
params.require(:subject).permit(:name, :position, :visible)
end
end
If I take the validations off it works, but then I can create the subject without a name. I noticed that if I add a subject the number in the paranthesis '3' moves up. I wonder if it has something to do with the select form. Here's the form:
<%= error_messages_for(#subject) %>
<table summary="Subject form fields" class="table table-hover">
<tr>
<th><%= f.label(:name, "Name") %></th>
<td><%= f.text_field(:name) %></td>
</tr>
<tr>
<th><%= f.label(:position) %></th>
<td><%= f.select(:position, 1..#subject_count) %></td>
</tr>
<tr>
<th><%= f.label(:visible) %></th>
<td><%= f.check_box(:visible) %></td>
</tr>
</table>
Update: I'm adding the index view per request.
<% #page_title = 'Subjects' %>
<div class="subjects show">
<h2>Subjects</h2>
<%= link_to("Add New Subject", {:action => 'new'}, :class => 'action new btn btn-default') %>
<table class="listing table table-hover" summary="Subject list">
<tr class="header">
<th>Position</th>
<th>Subject</th>
<th>Visible</th>
<th>Pages</th>
<th>Actions</th>
</tr>
<% #subjects.each do |subject| %>
<tr>
<td><%= subject.position %></td>
<td><%= subject.name %></td>
<td class="center"><%= subject.visible ? 'Yes' : 'No' %></td>
<td class="center"><%= subject.pages.size %></td>
<td class="actions">
<%= link_to("Show", {:action => 'show', :id => subject.id}, :class => 'action show') %>
<%= link_to("Edit", {:action => 'edit', :id => subject.id}, :class => 'action edit') %>
<%= link_to("Delete", {:action => 'delete', :id => subject.id}, :class => 'action delete') %>
</td>
</tr>
<% end %>
</table>
</div>
due to a syntax error for the partial on the else part of create action, active model was throwing an exception(http://apidock.com/rails/v3.2.1/ActionView/PartialRenderer/partial_path)
def create
#few lines escaped....
else
#subject_count = Subject.count + 1
render(new) # <-- Error
end
It should be either render :new or render 'new' as mentioned by Nobilik. your method should look like:
def create
#few lines escaped....
else
#subject_count = Subject.count + 1
render :new # for best practice
end
I am trying to set "edit" function for a simple CMS. I can make it to create/delete, but it just won't let me "edit".
here is the error message:
SyntaxError in SectionsController#edit
app/views/sections/edit.html.erb:42: syntax error, unexpected keyword_ensure, expecting keyword_end
Extracted source (around line #42):
40
41
when I checked my edit.html.erb. it seems fine?
'index'}, :class => 'back-link') %>
<div class="sections edit">
<h2>Update Sections</h2>
<%= form_for(:two, :url => {:action => 'update', :id => #one.id}) do |f| %>
<table summary="Section form fields">
<% #one.each do |f| %>
<tr>
<th>Name</th>
<td><%= f.text_field(:name) %></td>
</tr>
<tr>
<th>Position</th>
<td><%= f.text_field(:position) %></td>
</tr>
<tr>
<th>Visible</th>
<td><%= f.text_field(:visible) %></td>
</tr>
<tr>
<th>content_type</th>
<td><%= f.text_field(:content_type) %></td>
</tr>
<tr>
<th>content</th>
<td><%= f.text_field(:content) %></td>
</tr>
<tr>
<th>page_id</th>
<td><%= f.text_field(:page_id) %></td>
</tr>
</table>
<div class="form-buttons">
<%= submit_tag("Update Section") %>
</div>
<% end %>
</div>
Here is the controller:
class SectionsController < ApplicationController
def index
#one = Section.all
end
def show
#one = Section.find(params[:id])
end
def new
#one = Section.new
end
def create
#one = Section.new(section_params)
if #one.save
flash[:notice] = "Section created successfully!"
redirect_to(:action => 'index')
else
render('new')
end
end
def edit
#one = Section.find(params[:id])
end
def update
#one = Section.find(params[:id])
if #one.update_attributes(section_params)
flash[:notice] = "Subject updated successfully!"
redirect_to(:action => 'show', :id =>#one.id)
else
render('edit')
end
end
def delete
#one = Section.find(params[:id])
end
def destroy
subject = Section.find(params[:id]).destroy
flash[:notice] = "Subject deleted successfully!"
redirect_to(:action => 'index')
end
private
def section_params
params.require(:two).permit(:id,:name,:position,:visible,:page_id,:content,:content_type)
end
end
Thanks so much!!
Thanks #Pavan, #MarsAtomic and #Mandeep ! I found the issue: <% #one.each do |f| %>. I don't really need this line. If I need it, I need a end code for this.
In my case, I don't, so I go ahead deleted this line, and it worked now!
thanks again everyone!
Now, I tried to set up the route with group_path(#group) but got an error message like,
ActiveRecord::RecordNotFound at /groups/%23%3CActiveRecord::Relation:0x007fd6cf362538%3E
Couldn't find Group with id=#<ActiveRecord::Relation:0x00fds6cf362538>
Here is my code. I would like to set up a link to groups/show/:id. Why did this error occur? Could you give me how to solve this?
☆index.html.erb
<% if #items.present? %>
<% #items.each do |i| %>
<% i_attr = i.get_element('ItemAttributes') %>
<tr>
<td> <%= link_to image_tag(i.get('SmallImage/URL'), {:style => 'border: none;'}), i_attr.get('DetailPageURL') %></td>
<td> <%= link_to i_attr.get('Title'), i_attr.get('DetailPageURL') %></td>
<td> <%= i_attr.get('Author') %></td>
<td> <%= i_attr.get('PublicationDate')%></td>
<td> <%= i_attr.get('Publisher') %></td>
<td> <%= i_attr.get('NumberOfPages')%></td>
<td>
<% if #existing_groups_isbns.include? i_attr.get('ISBN') %>
<% #existing_groups_isbns.each do |isbn| %>
<% if isbn == i_attr.get('ISBN') %>
<% #group = Group.where(:isbn =>isbn) %>
<%= link_to '既存ページへ' , group_path(#group) %>
<% end %>
<% end %>
<% else %><!-- if includes?==-->
<%= link_to '新規作成', {:controller => 'groups', :action => 'new', :name => i.get('ItemAttributes/Title'),:author => i.get('ItemAttributes/Author'), :publish => i.get('ItemAttributes/Publisher'), :published => i.get('ItemAttributes/PublicationDate'), :isbn => i.get('ItemAttributes/ISBN'), :page => i.get('ItemAttributes/NumberOfPages'), :imageurl=>i.get('MediumImage/URL')} ,class: "btn btn-midium btn-primary"%>
<% end %><!--if includes?-->
</td>
</tr>
<% end %><!-- #items.each do-->
<% else %><!--if #items.present?-->
見つかりませんでした。
<% end %><!-- if #items.present?-->
☆index_controller
def index
#keyword = params[:keyword]
if #keyword.present?
Amazon::Ecs.debug = true
res = Amazon::Ecs.item_search(params[:keyword],
:search_index => 'All', :response_group => 'Medium')
#items = res.items
search_isbns = #items.map{ |isbns| isbns.get('ItemAttributes/ISBN')}
search_asins = #items.map{ |asins| asins.get('ItemAttributes/ASIN')}
#existing_groups_isbns = Group.select(:isbn).where(:isbn => search_isbns).map(&:isbn)
#existing_groups_ids = Group.where(:isbn => search_isbns).map{|g| g.id}
end
Replace
<% #group = Group.where(:isbn =>isbn) %>
with
<% #group = Group.where(:isbn =>isbn).first %>
Because you need an object where you had an ActiveRecord relation
Now I am trying to set up switching button to follow someone.
<div class="onoff">
<% unless session[:user_id] == member.id %>
<% if #isFr.friend_id == member.id %>
<%= link_to'off', {:controller => 'members', :action => 'index', :id =>
member.id}, class: "btn btn-midium btn-primary"%><br/>
※following
<% else %>
<%= link_to'on', {:controller => 'members', :action => 'index', :id =>
member.id}, class: "btn btn-midium btn-primary"%><br/>
※not following
<% end %>
<% end %>
</div-->
But I got an error message.
undefined method `friend_id' for #<ActiveRecord::Relation:0x007fc4b54935f0>
and looked into #isFr and it has
>> #isFr
=> [#<Friend id: 196, member_id: 2, friend_id: 3, created_at: "2013-12-23 01:28:18", updated_at: "2013-12-23 01:28:18">]
So, I can't extract friend_id value from #isFr.
How can I solve this?
☆members_controller
def index
if !checklogin? then return end
#members = Member.where("id >=1").order("created_at desc").paginate(:page => params[:page], :per_page => 10).scoped
if Friend.where(:member_id => session[:user_id], :friend_id => params[:id]).exists? then
Friend.where(:member_id => session[:user_id], :friend_id => params[:id]).each do |f|
f.destroy
end
else
Friend.new({:member_id => session[:user_id], :friend_id =>params[:id].to_i}).save
end
#isFr =Friend.where(:member_id => session[:user_id], :friend_id => #members.map(&:id)).limit(1)
respond_to do |format|
format.html # index.html.erb
format.json
end
end
☆index.html.erb(members#index)
<table class="table">
<tr>
<th>写真</th>
<th>名前</th>
<th>分野</th>
<th>場所</th>
<th>経験</th>
<th></th>
<%# if Member.find(session[:user_id]).admin %>
<%# end %>
</tr>
<% #members.each do |member| %>
<tr>
<td>
<% if member.provider %>
<%=image_tag member.image ,:size=>'30x30'%>
<% elsif member.avatar_file_name %>
<%= image_tag member.avatar.url(:thumb), :width =>'30px', :height =>'30px' %>
<% else %>
<%= image_tag "love.png", :size=>'30x30' %>
<% end %>
</td>
<td>
<%= member.name %>
<% if member.provider == "facebook" %>
<a target="_blank" href="http://www.facebook.com/<%=member.uid %>"> <%=image_tag "fb.png" ,:size=>'20x20'%> </a>
<% elsif member.provider == "twitter" %>
<a target="_blank" href="http://www.twitter.com/<%=member.name %>"> <%=image_tag "twitter.png" ,:size=>'20x20'%> </a>
<% end %>
</td>
<td><%= member.field %></td>
<td>
<% if member.url.present? %>
<%=link_to member.place ,member.url ,:target=>["_blank"] %>
<% else %>
<%= member.place %>
<% end %>
</td>
<td><%= member.experience %></td>
<td>
<div class="onoff">
<% unless session[:user_id] == member.id %>
<% if #isFr.friend_id == member.id %>
<%= link_to'off', {:controller => 'members', :action => 'index', :id =>
member.id}, class: "btn btn-midium btn-primary"%><br/>
※following
<% else %>
<%= link_to'on', {:controller => 'members', :action => 'index', :id =>
member.id}, class: "btn btn-midium btn-primary"%><br/>
※not following
<% end %>
<% end %>
</div-->
<%#= member.friends.count %>
</td>
<% if Member.find(session[:user_id]).admin %>
<td><%= link_to 'Destroy', member, method: :delete, data: { confirm: 'Are you sure?' } %></td>
<% end %>
</tr>
<% end %>
</table>
The problem is at this line
#isFr =Friend.where(:member_id => session[:user_id], :friend_id => #members.map(&:id)).limit(1)
That will respond a ActiveRecord::Relation but you need a Friend object. Try this
#isFr =Friend.where(:member_id => session[:user_id], :friend_id => #members.map(&:id)).first
I implemented a chat system to my app.
It refreshes the list of comments partially when after new comment was submit.
So new added comment pops up without reloading whole page.
It's working fine but the problem is, it won't make input field empty(initialize) after submit :(
How can I make it empty if it succeeded at submitting?
5 seconds Auto-refreshing will be another issue that's preventing.
So I have to care about it, too.
and If possible I want to pop up flash alert 'you cant spam' when the user tried to submit comment within 10 seconds.
Let's assume as if I'm trying to submit comment from Users#show page
views/users/show.html.erb
<%= javascript_tag do %>
jQuery(document).ready(function () {
refreshPartial();
setInterval(refreshPartial, 5000)
});
function refreshPartial() {
$.ajax({
url: "<%= show_user_path(#user) %>/refresh_part",
type: "GET",
dataType: "script",
});
}
<% end %>
......
<span id="chat">
<%= render 'users/comment' %>
</span>
<%= render 'users/comment_input' %>
views/users/_comment.html.erb
<table>
<tr>
<th>ID</th>
<th>PIC</th>
<th>Body</th>
<th>Subject</th>
<th>Posted by</th>
<th>Delete</th>
</tr>
<% #comments.each do |comment| %>
<tr id="<%= dom_id(comment) %>">
<td><%= comment.id %></td>
<td>
<% if comment.comment_icon? %>
<ul class="thumbnails">
<%= image_tag(comment.comment_icon.url(:thumb),:height => 100, :width => 100, :style => 'border:3px double #545565;' ) %>
</ul>
<% end %>
</td>
<td><%= comment.body %></td>
<td><%= comment.subject %></td>
<td><%= comment.user.user_profile.nickname if comment.user.user_profile %></td>
<td>
<%= button_to 'destroy', polymorphic_path([#user, comment]), :data => {:confirm => 'Are you sure?'}, :method => :delete, :disable_with => 'deleting...', :remote => true, :class => 'btn btn-danger' if current_user && current_user.id == comment.user_id %>
</td>
</tr>
<% end %>
</table>
<%= paginate #comments, :window => 4, :outer_window => 5, :left => 2, :right => 2 %>
views/users/_comment_input.html.erb <= This is input form!!!!!
<%=form_for(([#user, #comment]), :remote => true) do |f| %>
<div class="field">
<%= f.label :body %><br />
<%= f.text_field :body %>
</div>
<div class="field">
<%= f.file_field :comment_icon %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
comments_controller.rb
def create
commentable = #community_topic||#community||#user
#comments = commentable.comment_threads.order("updated_at DESC").page(params[:page]).per(5)
#comment = Comment.build_from(commentable, current_user.try(:id), params[:comment][:body])
#comment.comment_icon = params[:comment][:comment_icon]
if #user
#following_users = #user.all_following(order: 'updated_at DESC')
#followed_users = #user.followers
#communities_user = #user.get_up_voted(Community).order("updated_at ASC").page(params[:page]).per(5)
elsif #community
end
last_comment = Comment.where(:user_id => current_user.id).order("updated_at").last
if last_comment && (Time.now - last_comment.updated_at) <= 10.second
flash[:notice] = "You cannot spam!"
render :template => template_for(commentable)
elsif #comment.save
#if #community_topic.empty?
#comments = commentable.comment_threads.order("updated_at DESC").page(params[:page]).per(5)
#comment = commentable.comment_threads.build
respond_to do |format|
format.html { redirect_to [#community, commentable].uniq, :notice => "comment added!" }
format.js do
if #community.present?
render 'communities/refresh_part'
elsif #community_topic.present?
render 'community_topics/refresh_part'
elsif #user.present?
render 'users/refresh_part'
end
end
end
else
render :template => template_for(commentable)
end
end
views/users/refresh_part.js.erb
$('#chat').html("<%= j(render(:partial => 'users/comment')) %>")
Well I assume this is the "body" input you want to empty so basically, just add an id to it like this :
<%= f.text_field :body, :id => "body_input" %>
And in your views/users/refresh_part.js.erb, you can add something like :
$('#body_input').val('');
This should work only if it succeded at submitting because from what I saw, your template is rendered only if the comment is saved.