Activity
I achieved to put homedir of the restricted FTP user in my deployed app
Do you mean you physically moved the users FTP folder into your rails app folder? Or did you just create the symlink?
If you moved it, then I don't think I'd go that route as the symlink method will give you the exact same access without the negative side effects of moving a user's home directory inside your app.
Let's say the files you're trying to access are located here:
/home/user1/uploads
And you want your app to access the zip file here:
/var/www/your_rails_app/cron/files
Then your symlink command that you'd type in the terminal (not rails console) would look like this:
ln -s /home/user1/uploads /var/www/your_rails_app/cron/files
If you haven't watched it already, Chris has a wonderful video on the Whenever gem you should check out: https://gorails.com/episodes/cron-jobs-with-whenever-gem
Your first_or_create method allows you to check attributes on the found or created object, you just need to remove the post_body params and assign them later to do what you want:
@new_post = Post.where(external_id: post_body[:external_id]).first_or_create if @new_post.mod_time.present? #update record # do whatever updating you want else #it's a new record post['objects']['img'].each do |media| @new_post.images.build( external_id: media['external_id'], mod_time: media['mod_time'], url: media['url'], format: media['format'] ) end @new_post.assign_attributes(post_params) @new_post.save # you may be able to get away with just doing @new_post.update(post_params) but I can't recall if it # will save your newly created association as well, so you'll want to tinker with it some. end
This might take care of your last issue as well, but I'm not 100% sure I understand what the issue is there so play with this some and if it doesn't then post back.
No problem at all, good luck!
You can still set it thanks to the has_one:
class Site < ApplicationRecord
def slug_candidates
[
user.first_name,
[user.first_name, user.last_name],
[user.first_name, user.last_name, user.id],
]
end
end
Can you post your method you use for friendly_id to create the subdomain? As long as it runs the `slugginator` after save when it will have the user_id then you should be good
If so, then just this would work:
class SitesController < ActionController::Base def create @user = User.find(params[:user_id]) @site = @user.build_site.save end end
There's no need to mess with site_params in this case since you're not passing any of that information to the new record yet. So just pass the user_id, find that user, then use the build_site method to create the association and then call save to commit it all to the DB.
Can you provide a specific use case that prohibits this setup from working for your needs? How are you querying for your :subdomain and :main_domain that would keep you from getting the desired result?
You could be completely correct for your use case, I'm just not tracking yet is all :)
class Site < ApplicationRecord belongs_to :user end
class User < ApplicationRecord has_one :site end
Now you can build the association like so:
user.build_site
Will the file name always be the same? If so, you could create a symbolic link to the file to your public directory... so something like:
ln -s /home/path/to/file.ftp /path/to/rails/public/
You could also designate a folder in their home directory and then just symlink that directory instead and access any files placed in that directory. Just mind your security since you are putting it in the public directory.
Here's a basic setup to get an ajax request to render your partial
function getMonth(data, callback) { $.ajax({ url: '<%= your_action_url %>', type: 'GET', data: data, success: callback }); }
I usually make a new action in the controller to handle the request, but it's not necessary:
def dates @date = params[:date] ? Date.parse(params[:date]) : Date.today end
If you know ahead of time, then you can just create a loop to keep running the `getDate();` function. Since you'll probably need to pass the date as a param, you can do a slight tweak as follows:
function getDate(date, data, callback) { $.ajax({ url: "<%= your_action_url %> + '?date=' + date", type: 'GET', data: data, success: callback }); } var dates = ["01-01-2018", "01-02-2018", "01-03-2018",...] for (var i in date) { getDate(date); }
*edits: looks like the normal markdown parser isn't working? Had to use the form controls instead =(
Posted in Setup for roles and authorization
Excellent!! Glad to hear you got it working, and good to know Rolify isn't necessary for this kind of setup.
Good luck!!
Hey Mark,
I think Jacks answer is the more railsy way of doing this, so if you're worried about convention then that's probably your best bet.
However, you're already stepping outside the normal rails convention space by utilizing a view model pattern, so really your idea of making another method inside your view model probably fits better with your design.
Just my thoughts FWIW, good luck!
Posted in Setup for roles and authorization
Not that I'm aware of, I think the first time I typed it I did ProjectRole
but then changed to ProjectMembership
just for the sake of continuity between the article and what was being said here.
For this case, I'd say it really depends on what else you may need this table to do for you. If all it's going to do is manage the roles and absolutely nothing else, then ProjectRole
is probably the most descriptive. However, if you plan on storing other info there as well, maybe activity the users activity or some preferneces that are particular to that project/membership relation, then a different name would probably be more appropriate since it's doing more than just handling roles.
Posted in Setup for roles and authorization
No worries at all, this stuff can be confusing!
It kind of depends on what your final needs are and the level of granularity you need. I'd say if you can control all foreseeable actions by a simple enum role system, then just roll with that on your ProjectMembership
model and let cancancan handle all the logic from there.
Unfortunately, I don't have enough experience working with either of them to give an example of some of the nuances, my usual setup is just an enum role + action_access gem since my needs are usually pretty simple.
I'd create a dummy app and do a few quick tests of the model configuration + cancancan and see if you can hammer out a few expected situations and see how it works out for you. If you hit a snag, see if that's something that Rolify could help out with. Tinkering is my favorite part of the process! :)
Posted in Setup for roles and authorization
Hey Nick,
Welcome!!
Something you may consider is adding another table, ProjectMembership
and then setup has_many :through
relations between your users and projects via that table.
class User < ActiveRecord::Base
has_many :projects, :through => :project_memberships
has_many :project_memberships
end
This should take care of your problem of a user having various roles based on the particular project their assigned. Check out this SO for additional details: https://stackoverflow.com/questions/11600928/when-should-one-use-a-has-many-through-relation-in-rails
I don't have a ton of experience with cancancan/rolify, but based on my understanding they kind of serve different purposes so you will probably want to use them together. Cancancan is focused on authorization which you scope based on the roles you setup with rolify. So you let cancancan manage authorization logic, and let rolify manage the role logic.
Hi Mark,
Can you post your routes and the link_to
you're using?
Posted in Implementing global app settings
Hi RJ,
If you want a gem solution, you can look at the rails-settings gem: https://github.com/ledermann/rails-settings
I haven't used it personally so I can't give much details, but it does look like they have a decent syntax. I generally just do as you and Andrew suggested, a single table with one row for app wide settings.
Posted in Implementing Highcharts in RoR
Hey John,
You'll have to do some playing around here, but if you take a look at this JSFiddle: http://jsfiddle.net/nanosplit/xv7vut53 I've simplified it down to the bare bones of what's needed to accomplish what you want as if it were hard coded. So now all you have to do is figure out how to make it interactive... this is where ajax comes into play.
Below is pretty much the same thing as the fiddle above, but I've swapped out the hard coded parts to make an ajax call.
foo_controller.rb
def get_updated_data
series_name = "New Data"
series_data = [40000, 50000, 60000, 70000, 80000, 90000, 100000, 120000]
@chart_data = [series_name, series_data]
respond_to do |format|
format.json { render json: @chart_data }
end
end
$(function () {
chart: new Highcharts.Chart({
chart: {
renderTo: 'container'
},
series: [{
name: 'Old Data',
data: [43934, 52503, 57177, 69658, 97031, 119931, 137133, 154175]
}]
});
$('#button').click(function () {
var chart = $('#container').highcharts();
var url = "/get_updated_data"
$.ajax({
type: "GET",
dataType: "json",
url: url,
success: function(data){
newDataName = data[0]
newData = data[1]
var new_series = [{
"name": newDataName,
"data": newData,
}];
for (var i = chart.series.length-1; i>=0; i--) {
chart.series[i].remove();
}
for (var y = new_series.length-1; y >= 0; y--) {
chart.addSeries(new_series[y]);
}
}
});
});
});
For example, I assume I draw the chart in the main HTML page, then when they filter the data I use a javascript callback to change the data?
Yes, basically what you want to do is change the button click function above into a regular function that accepts parameters which you'll then use to construct a new url which the ajax call will use to fetch your new data and then render it
function updateChart(param1, param2) {
var chart = $('#container').highcharts();
var url = "/get_updated_data?param1=" + param1 + "¶m2=" + param2
... rest of the stuff above
So your callback would need to call updateChart()
and pass in the params based on what the user selected - updateChart(foo, bar)
You'll want to make the params part more dynamic since you're probably not going to know ahead of time how many parameters you'll be feeding at once, but this should get you rolling.
Hi Linards,
I think what Jack is referring to is your comments controller create action:
class CommentsController < ApplicationController
def create
@comment = current_user.comments.build(comment_params)
end
private
def comment_params
params.require(:comment).permit(:content) #you're only allowing :content
end
end
Your comment params are only permitting :content
and in your new comment form you don't pass the blog ID either:
<% unless current_user.is_a? GuestUser %>
<%= form_for @comment, url: '#' do |f| %>
<div class="form-group">
<%= f.label :content %>
<%= f.text_area :content, class: 'form-control' %>
</div>
<%= f.submit 'Post Comment', class: 'btn btn-primary' %>
<% end %>
<% end %>
And in your show action you're just creating a new comment without associating the @blog.id
:
def show
@blog = Blog.includes(:comments).friendly.find(params[:id])
@comment = Comment.new # you should be building the comment from the blog
end
So what you should be able to do is something like:
def show
@blog = Blog.includes(:comments).friendly.find(params[:id])
@comment = @blog.comments.build
end
Which should now properly pass the :blog_id
. You may have to play with this some, I haven't tested and I've only had one cup of coffee so my brains not firing on all cylinders yet but this should get you going in the right direction.
You could also do something like this (but the above is the more railsy way)
<% unless current_user.is_a? GuestUser %>
<%= form_for @comment, url: '#' do |f| %>
<div class="form-group">
<%= f.label :content %>
<%= f.text_area :content, class: 'form-control' %>
<%= f.hidden_field :blog_id, @blog.id %>
</div>
<%= f.submit 'Post Comment', class: 'btn btn-primary' %>
<% end %>
<% end %>
And then just add to your permitted params:
class CommentsController < ApplicationController
def create
@comment = current_user.comments.build(comment_params)
end
private
def comment_params
params.require(:comment).permit(:content, :blog_id)
end
end