Was asked today to implement a simple application that lets people submit tickets without persisting them to the database. This is going to work perfectly. Thanks Ryan!
I'm running into a strange problem with cucumber. When I run my feature that tests that a user can create an account, the feature fails with the error No route matches [POST] "/auth/identity/register" (ActionController::RoutingError) It does, however, work just fine if I test it in my browser. Running rake routes dos not show that route, but I assume that's because it's provided by omniauth-identity through rack middleware. Does anyone have any ideas? Any Google searches I've done just bring me back here. Thanks for the great screencast!
When I save the data and want to edit them again, only the first select is shown.
The second select is on "style="display: none" regardless the right values is "option selected="selected".
For anyone still referencing this, current ActiveRecord versions now have a reset_counters convenience class method that will automatically execute a count query for you. Also, please do use find_each instead of find(:all).each :-)
I'm not wild about using migrations to modify data personally, but if you insist:
Hi Ryan,
i see that there are some hooks you can define using delayed job.
i want to do some task after the job is done and, as the docs suggest i add the method
ruby
defafter(job)
# do somethingend
in my class but it never been called.
What is the right way to use the hooks or maybe there is some other way to define callbacks instead?
I have modified the 'before' app according to the section in the example titled 'Using Private Pub in Our Applications' but private pub is failing. I am looking for troubleshooting help.
I am running Rails 3.2.
I do not see a new message appear in the browser until I refresh the screen. The development log looks good. Index.html is being rendered, just not to the browser. Here is the log:
Started GET "/" for 135.209.108.81 at 2012-02-20 15:46:37 -0800
Processing by MessagesController#index as /
Message Load (8.2ms) SELECT messages.* FROM messages
Rendered messages/_message.html.erb (90.4ms)
Rendered messages/index.html.erb within layouts/application (94.5ms)
Completed 200 OK in 132ms (Views: 109.4ms | ActiveRecord: 8.9ms)
Only after I refresh either broswer do I see the chat list. In the log, after the refresh, we see:
Started GET "/assets/application.css?body=1" for 135.209.108.81 at 2012-02-20 15:46:38 -0800
Served asset /application.css - 304 Not Modified (0ms)
Started GET "/assets/messages.css?body=1" for 135.209.108.81 at 2012-02-20 15:46:38 -0800
Served asset /messages.css - 304 Not Modified (0ms)
Beofre I modified the chatter-before app as per the tutorial, the browser submitting the update was updated by ajax. Now, after the modification to use private_pub, the submitting browser must be refreshed to see a new message.
When pointing the browser at the http://myserver:9292, the server responds with the following message:
Sure you're not looking for /faye ?
Thanks. I will post the solution when I know what it is.
Looks good but seems to have a conflict with cancan (both current release and 2.0 alpha). Would post a bug report but not really sure which gem is the culprit.
On a brand new rails 3.2.1 app with only cancan and rabl added to Gemfile:
/usr/local/rvm/gems/ruby-1.9.3-p125@***/gems/rabl-0.2.8/lib/rabl/template.rb:66:in `<top (required)>': uninitialized constant ActionView::TemplateHandlers (NameError)
from /usr/local/rvm/gems/ruby-1.9.3-p125@***/gems/rabl-0.2.8/lib/rabl.rb:12:in `register!'
from /usr/local/rvm/gems/ruby-1.9.3-p125@***/gems/rabl-0.2.8/lib/rabl/railtie.rb:6:in `block (2 levels) in <class:Railtie>
<snip>'
Here's how I did it for a blog project using Rails 3.2 and Redcarpet 2.1 (minus the syntax highlighting). Some of the configuration options have been moved into the HTML renderer, while the more generic ones are still at the markdown layer:
Thanks for the railscast, Gon looks very promising!
My only fear is that google won't index anything more then 'Loading products...', making this technique unusable for certain projects. Are there any solutions known for this problem?
Apparently the DB queries is not the bottleneck for most cases, if you can avoid complex joints, etc... This came as a surprise to me too. (See the linked 37Signals article and the comments)
@Ryan in HTTP caching you can only fix expiration once.
So, if you set a TTL of 30 minutes for a page, you're done. No way to tell the users and intermediate proxy caches that fetched that one they need to revalidate right now because it is stale. They won't do it after 30 minutes have passed.
So, the key of this approach vs HTTP headers is that you have total control over the expiration of the cache.
I think the main problem with this approach is that you have to load and use all the recent article models, even when you read from the cache.
If you already have the article models loaded just to build the name of the cache, you might as well just print the link_to entries and skip the cache altogether. I would think the main benefit of caching this section of the page would be to avoid the SQL call that loads the recent article models in the first place.
When I was going through the RailsCast as described above. I was using the entries controller that Ryan put together. After much searching, copying, pasting, and retrying I found that I need a completely new Controller set up. Below is what I originally had.
class EntriesController < ApplicationController
respond_to :json
def index
respond_with Entry.all
end
def show
respond_with Entry.find(params[:id])
end
def create
respond_with Entry.create(params[:entry])
end
def update
respond_with Entry.update(params[:id], params[:entry])
end
def destroy
respond_with Entry.destroy(params[:id])
end
end
This is the Controller code the fixed the issue for me.
class EntriesController < ApplicationController
def index
render :json => Entry.all
end
def show
render :json => Entry.find(params[:id])
end
def create
entry = Entry.create! params
render :json => entry
end
def update
entry = Entry.find(params[:id])
entry.update_attributes!(params[:entry])
render :json => entry
end
def destroy
render :json => Entry.destroy(params[:id])
end
end
I'm doing ExtJs for some time and bumped to similar problem, at beginning, cause I was lazy to rewrite validation to client side. Then I realized that VALIDATION is not same as BUSINESS RULES in your app.
There is nothing wrong having same validation in UI. It will just prevent UI to make unnecessary round trips to backend. So add that validation in UI. Also, you can pass exceptions for Business rules back to ui by packing exception as nice messages which you can send with HTTP 4xx or 5xx status codes. Or you can add special JSON/XML node which your javascript code will handle before response reaches your UI model.
After all, UI validation is always more restrictive than one which is in service ;)
I did a variant of the above Raffler in Spine JS to find out the differences between Spine JS and Backbone. For those of you that are interested, the result can be found here: https://github.com/ygor/spine-raffler
The only thing that I have not been able to figure out yet is how to do the remote validation. Let me know what you think!
In my controller I have to add "@product.category_ids = params[:product][:category_ids]" to the create and update actions, otherwise nothing gets stored in the database. I don't see this in the source code of this episode. Am I forgetting something?
Great Episode!
I'm using modest model. It's very similar and an alternative if someone is looking for.
have_xpath
is an RSpec matcher.Has anyone got capybara xpath assertions working?
Example:
page.should have_xpath("//title")
Gives me the error:
NoMethodError: undefined method `have_xpath'
What advantages does MiniTest have over other existing testing frameworks? Other than having "Mini" in the name.
Does the final setup here use transactions in the db for isolation? If so, which part of the setup loads that support? I couldn't see it.
why backbone submit with double params?
Was asked today to implement a simple application that lets people submit tickets without persisting them to the database. This is going to work perfectly. Thanks Ryan!
I'm running into a strange problem with cucumber. When I run my feature that tests that a user can create an account, the feature fails with the error
No route matches [POST] "/auth/identity/register" (ActionController::RoutingError)
It does, however, work just fine if I test it in my browser. Runningrake routes
dos not show that route, but I assume that's because it's provided byomniauth-identity
through rack middleware. Does anyone have any ideas? Any Google searches I've done just bring me back here. Thanks for the great screencast!I thought to this article as soon as the episode started! =)
Well, there's also the fact that server rendering is holding up a blocking request. Time/throughput is more expensive than memory.
Thanks for the hint -- exactly what I needed for my "legacy" app.
When I save the data and want to edit them again, only the first select is shown.
The second select is on "style="display: none" regardless the right values is "option selected="selected".
Any suggestions?
Thanks ahead!
Thanks Ryan! Private_pub really is a Gem. May I suggest a tiny, tiny, three character tweak would make it even more fun:
In app/views/messages/create.js.erb,
Change ".append" to ".prepend", like this:
<% publish_to "/messages/new" do %>
$("#chat").prepend("<%= j render(@message) %>");
<% end %>
$("#new_message")[0].reset();
Restart Mongrel (or your WebServer).
Now, each new micropost will be on top, and you won't have to scroll using the side bar to view it at the bottom.
Yes. I also have this issue. Rails 3.2.1 with rabl.
For anyone still referencing this, current ActiveRecord versions now have a
reset_counters
convenience class method that will automatically execute a count query for you. Also, please do usefind_each
instead offind(:all).each
:-)I'm not wild about using migrations to modify data personally, but if you insist:
Hi Ryan,
i see that there are some hooks you can define using delayed job.
i want to do some task after the job is done and, as the docs suggest i add the method
in my class but it never been called.
What is the right way to use the hooks or maybe there is some other way to define callbacks instead?
And the problem was: The browser. Works in Firefox 9.0.1. Cheers.
Hello Ryan and All,
I have modified the 'before' app according to the section in the example titled 'Using Private Pub in Our Applications' but private pub is failing. I am looking for troubleshooting help.
I am running Rails 3.2.
I do not see a new message appear in the browser until I refresh the screen. The development log looks good. Index.html is being rendered, just not to the browser. Here is the log:
Started GET "/" for 135.209.108.81 at 2012-02-20 15:46:37 -0800
Processing by MessagesController#index as /
Message Load (8.2ms) SELECT
messages
.* FROMmessages
Rendered messages/_message.html.erb (90.4ms)
Rendered messages/index.html.erb within layouts/application (94.5ms)
Completed 200 OK in 132ms (Views: 109.4ms | ActiveRecord: 8.9ms)
Only after I refresh either broswer do I see the chat list. In the log, after the refresh, we see:
Started GET "/assets/application.css?body=1" for 135.209.108.81 at 2012-02-20 15:46:38 -0800
Served asset /application.css - 304 Not Modified (0ms)
Started GET "/assets/messages.css?body=1" for 135.209.108.81 at 2012-02-20 15:46:38 -0800
Served asset /messages.css - 304 Not Modified (0ms)
Beofre I modified the chatter-before app as per the tutorial, the browser submitting the update was updated by ajax. Now, after the modification to use private_pub, the submitting browser must be refreshed to see a new message.
When pointing the browser at the http://myserver:9292, the server responds with the following message:
Sure you're not looking for /faye ?
Thanks. I will post the solution when I know what it is.
Looks good but seems to have a conflict with cancan (both current release and 2.0 alpha). Would post a bug report but not really sure which gem is the culprit.
On a brand new rails 3.2.1 app with only cancan and rabl added to Gemfile:
Anyone else seeing this?
Post is by DHH, the name you mention is from a comment. ;-)
Here's how I did it for a blog project using Rails 3.2 and Redcarpet 2.1 (minus the syntax highlighting). Some of the configuration options have been moved into the HTML renderer, while the more generic ones are still at the markdown layer:
RABL crashes for me on rails 3.2.1 on ruby 1.9.2
/Users/rackom/.rvm/gems/ruby-1.9.2-p290/gems/rabl-0.2.8/lib/rabl/template.rb:66:in <top (required)>: uninitialized constant ActionView::TemplateHandlers (NameError)
jbuilder on same configuration throws this error
Illegal instruction: 4
Any help?
Thanks for the railscast, Gon looks very promising!
My only fear is that google won't index anything more then 'Loading products...', making this technique unusable for certain projects. Are there any solutions known for this problem?
Also - can anyone explain how hook_for is supposed to work?
No need now. I'm using the Haml_Coffee_Assets gem referenced above. Textmate treats the hamlc files just like haml
Thanks from me also. The templates look allot cleaner now.
I saw that - great read! Makes sense.
What Textmate bundle do you use for .eco files ? I notice the bottom of your textmate window says javascript template. Where can I get it?
Has anyone done this with eco?
Good point. (This will most likely result in a different SQL query due to lazy/last-minute evaluation in AR, probably for the better...)
Apparently the DB queries is not the bottleneck for most cases, if you can avoid complex joints, etc... This came as a surprise to me too. (See the linked 37Signals article and the comments)
@Ryan in HTTP caching you can only fix expiration once.
So, if you set a TTL of 30 minutes for a page, you're done. No way to tell the users and intermediate proxy caches that fetched that one they need to revalidate right now because it is stale. They won't do it after 30 minutes have passed.
So, the key of this approach vs HTTP headers is that you have total control over the expiration of the cache.
I think the main problem with this approach is that you have to load and use all the recent article models, even when you read from the cache.
If you already have the article models loaded just to build the name of the cache, you might as well just print the link_to entries and skip the cache altogether. I would think the main benefit of caching this section of the page would be to avoid the SQL call that loads the recent article models in the first place.
check out this http://37signals.com/svn/posts/3113-how-key-based-cache-expiration-works Sofia Cardita of 37 signals does a great job explaining caching
You could use something like Article.maximum(:updated_at) as a cache key to make it shorter.
Does it make sense to nest cache resources this way? Is it Rails so slow to render a template that you should waste more cache memory?
A quick test in the console suggests that this should work (although you probably won't want to do this when you have a lot of objects in you array?)
What's a good way to auto-expire the "recent_articles" fragment you have there? Would something like this work?
A related blog post by 37Signals on this technique: http://37signals.com/svn/posts/3112-how-basecamp-next-got-to-be-so-damn-fast-without-using-much-client-side-ui
Our wishes came true. And so soon!
http://railscasts.com/episodes/90-fragment-caching-revised
Thanks Ryan!
When I was going through the RailsCast as described above. I was using the entries controller that Ryan put together. After much searching, copying, pasting, and retrying I found that I need a completely new Controller set up. Below is what I originally had.
This is the Controller code the fixed the issue for me.
Thanks All!
Travis
I'm doing ExtJs for some time and bumped to similar problem, at beginning, cause I was lazy to rewrite validation to client side. Then I realized that VALIDATION is not same as BUSINESS RULES in your app.
There is nothing wrong having same validation in UI. It will just prevent UI to make unnecessary round trips to backend. So add that validation in UI. Also, you can pass exceptions for Business rules back to ui by packing exception as nice messages which you can send with HTTP 4xx or 5xx status codes. Or you can add special JSON/XML node which your javascript code will handle before response reaches your UI model.
After all, UI validation is always more restrictive than one which is in service ;)
This worked awesome, thanks. It turns out oh-my-zsh added a ton of stuff to my path!
+1 for handling associations!
Thanks, that worked.
I agree, it was the first screencast that made me easily understand BB. Great job Ryan! Would be great to see a Ember screencast too!
verify that you can access the category_id column via mass assignment.
Add category_id to the attr_accessible declaration in your model
Hi,
I did a variant of the above Raffler in Spine JS to find out the differences between Spine JS and Backbone. For those of you that are interested, the result can be found here: https://github.com/ygor/spine-raffler
The only thing that I have not been able to figure out yet is how to do the remote validation. Let me know what you think!
In my controller I have to add "@product.category_ids = params[:product][:category_ids]" to the create and update actions, otherwise nothing gets stored in the database. I don't see this in the source code of this episode. Am I forgetting something?
There's this one, but it's over 4 years old:
http://railscasts.com/episodes/90-fragment-caching
Would love to see a 'revised' version of that one. I'm guessing it's coming up though.